CPUMR0.cpp revision d099ccfb66d26601f93e7967e8e73cee4b9c62df
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * CPUM - Host Context Ring 0.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * available from http://www.virtualbox.org. This file is free software;
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * General Public License (GPL) as published by the Free Software
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * additional information or have any questions.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync/*******************************************************************************
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync* Header Files *
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync*******************************************************************************/
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * Does Ring-0 CPUM initialization.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * This is mainly to check that the Host CPU mode is compatible
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * with VBox.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * @returns VBox status code.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * @param pVM The VM to operate on.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * Check CR0 & CR4 flags.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync if ((u32CR0 & (X86_CR0_PE | X86_CR0_PG)) != (X86_CR0_PE | X86_CR0_PG)) /* a bit paranoid perhaps.. */
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync Log(("CPUMR0Init: PE or PG not set. cr0=%#x\n", u32CR0));
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * Check for sysenter and syscall usage.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * Intel docs claim you should test both the flag and family, model &
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * stepping because some Pentium Pro CPUs have the SEP cpuid flag set,
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * but don't support it. AMD CPUs may support this feature in legacy
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * mode, they've banned it from long mode. Since we switch to 32-bit
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * mode when entering raw-mode context the feature would become
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * accessible again on AMD CPUs, so we have to check regardless of
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync * host bitness.
dacca731fbf5be1719e830909aaf86bceee18e1dvboxsync ASMCpuId(1, &u32CpuVersion, &u32Dummy, &u32Dummy, &fFeatures);
|| !ASMIsIntelCpu())
if (u32)
#ifdef RT_ARCH_X86
# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
if (!ASMIsIntelCpu())
return VINF_SUCCESS;
Assert( ((pCtx->cr0 & (X86_CR0_MP | X86_CR0_EM | X86_CR0_TS)) == (X86_CR0_MP | X86_CR0_EM | X86_CR0_TS))
return VINF_EM_RAW_GUEST_TRAP;
return VINF_EM_RAW_GUEST_TRAP;
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
# if defined(VBOX_WITH_HYBRID_32BIT_KERNEL) || defined(VBOX_WITH_KERNEL_USING_XMM) /** @todo remove the #else here and move cpumHandleLazyFPUAsm back to VMMGC after branching out 3.0!!. */
/* Clear MSR_K6_EFER_FFXSR or else we'll be unable to save/restore the XMM state with fxsave/fxrstor. */
/* Clear MSR_K6_EFER_FFXSR or else we'll be unable to save/restore the XMM state with fxsave/fxrstor. */
/* If we sync the FPU/XMM state on-demand, then we can continue execution as if nothing has happened. */
* The MSR_K6_EFER_FFXSR feature is AMD only so far, but check the cpuid just in case Intel adds it in the future.
* MSR_K6_EFER_FFXSR changes the behaviour of fxsave and fxrstore: the XMM state isn't saved/restored
/** @todo Do we really need to read this every time?? The host could change this on the fly though. */
Assert((pVCpu->cpum.s.fUseFlags & (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)) == (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM));
return VINF_SUCCESS;
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
# ifdef VBOX_WITH_KERNEL_USING_XMM
/* Clear MSR_K6_EFER_FFXSR or else we'll be unable to save/restore the XMM state with fxsave/fxrstor. */
# ifdef VBOX_WITH_KERNEL_USING_XMM
# ifdef VBOX_WITH_KERNEL_USING_XMM
return VINF_SUCCESS;
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
if (fDR6)
return VINF_SUCCESS;
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
if (fDR6)
return VINF_SUCCESS;
AssertCompile((uintptr_t)&pVCpu->cpum.s.Host.dr3 - (uintptr_t)&pVCpu->cpum.s.Host.dr0 == sizeof(uint64_t) * 3);
return VINF_SUCCESS;
AssertCompile((uintptr_t)&pVCpu->cpum.s.Host.dr3 - (uintptr_t)&pVCpu->cpum.s.Host.dr0 == sizeof(uint64_t) * 3);
return VINF_SUCCESS;
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
AssertFailed();
return VERR_NOT_IMPLEMENTED;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
if (fDR6)
return VINF_SUCCESS;