CPUMAllRegs.cpp revision 4bfa7b58e362a1bca0628643c352c137900bf01a
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * CPUM - CPU Monitor(/Manager) - Getters and Setters.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Copyright (C) 2006-2012 Oracle Corporation
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * available from http://www.virtualbox.org. This file is free software;
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * General Public License (GPL) as published by the Free Software
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync/*******************************************************************************
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync* Header Files *
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync*******************************************************************************/
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync/** Disable stack frame pointer generation here. */
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Sets or resets an alternative hypervisor context core.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * This is called when we get a hypervisor trap set switch the context
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * core with the trap frame on the stack. It is called again to reset
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * back to the default context core when resuming hypervisor execution.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @param pVCpu The VMCPU handle.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @param pCtxCore Pointer to the alternative context core or NULL
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * to go back to the default context core.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMHyperSetCtxCore(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync LogFlow(("CPUMHyperSetCtxCore: %p/%p/%p -> %p\n", pVCpu->cpum.s.CTX_SUFF(pHyperCore), pCtxCore));
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync pVCpu->cpum.s.pHyperCoreR3 = (R3PTRTYPE(PCPUMCTXCORE))VM_R3_ADDR(pVM, pCtxCore);
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync pVCpu->cpum.s.pHyperCoreR0 = (R0PTRTYPE(PCPUMCTXCORE))VM_R0_ADDR(pVM, pCtxCore);
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync pVCpu->cpum.s.pHyperCoreRC = (RCPTRTYPE(PCPUMCTXCORE))VM_RC_ADDR(pVM, pCtxCore);
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync pVCpu->cpum.s.pHyperCoreR3 = (R3PTRTYPE(PCPUMCTXCORE))MMHyperCCToR3(pVM, pCtxCore);
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync pVCpu->cpum.s.pHyperCoreR0 = (R0PTRTYPE(PCPUMCTXCORE))MMHyperCCToR0(pVM, pCtxCore);
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync pVCpu->cpum.s.pHyperCoreRC = (RCPTRTYPE(PCPUMCTXCORE))MMHyperCCToRC(pVM, pCtxCore);
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Gets the pointer to the internal CPUMCTXCORE structure for the hypervisor.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * This is only for reading in order to save a few calls.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @param pVM Handle to the virtual machine.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVMCPU pVCpu)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Queries the pointer to the internal CPUMCTX structure for the hypervisor.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @returns VBox status code.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @param pVM Handle to the virtual machine.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @param ppCtx Receives the hyper CPUMCTX pointer when successful.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @deprecated This will *not* (and has never) given the right picture of the
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * hypervisor register state. With CPUMHyperSetCtxCore() this is
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * getting much worse. So, use the individual functions for getting
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * and esp. setting the hypervisor registers.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(int) CPUMQueryHyperCtxPtr(PVMCPU pVCpu, PCPUMCTX *ppCtx)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperGDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperIDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperCR3(PVMCPU pVCpu, uint32_t cr3)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync /* Update the current CR3. */
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperCS(PVMCPU pVCpu, RTSEL SelCS)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperDS(PVMCPU pVCpu, RTSEL SelDS)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperES(PVMCPU pVCpu, RTSEL SelES)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperFS(PVMCPU pVCpu, RTSEL SelFS)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperGS(PVMCPU pVCpu, RTSEL SelGS)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperSS(PVMCPU pVCpu, RTSEL SelSS)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperESP(PVMCPU pVCpu, uint32_t u32ESP)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(int) CPUMSetHyperEFlags(PVMCPU pVCpu, uint32_t Efl)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync pVCpu->cpum.s.CTX_SUFF(pHyperCore)->eflags.u32 = Efl;
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperEIP(PVMCPU pVCpu, uint32_t u32EIP)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperTR(PVMCPU pVCpu, RTSEL SelTR)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperLDTR(PVMCPU pVCpu, RTSEL SelLDTR)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperDR0(PVMCPU pVCpu, RTGCUINTREG uDr0)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync /** @todo in GC we must load it! */
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperDR1(PVMCPU pVCpu, RTGCUINTREG uDr1)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync /** @todo in GC we must load it! */
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperDR2(PVMCPU pVCpu, RTGCUINTREG uDr2)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync /** @todo in GC we must load it! */
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperDR3(PVMCPU pVCpu, RTGCUINTREG uDr3)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync /** @todo in GC we must load it! */
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperDR6(PVMCPU pVCpu, RTGCUINTREG uDr6)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync /** @todo in GC we must load it! */
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(void) CPUMSetHyperDR7(PVMCPU pVCpu, RTGCUINTREG uDr7)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync /** @todo in GC we must load it! */
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync return pVCpu->cpum.s.CTX_SUFF(pHyperCore)->eflags.u32;
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(uint32_t) CPUMGetHyperIDTR(PVMCPU pVCpu, uint16_t *pcbLimit)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVMMDECL(uint32_t) CPUMGetHyperGDTR(PVMCPU pVCpu, uint16_t *pcbLimit)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Gets the pointer to the internal CPUMCTXCORE structure.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * This is only for reading in order to save a few calls.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @param pVCpu Handle to the virtual cpu.
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifdef IN_RC
AssertMsg((HyperCR0 & (X86_CR0_TS | X86_CR0_MP)) == (X86_CR0_TS | X86_CR0_MP), ("%#x\n", HyperCR0));
# ifdef VBOX_STRICT
AssertMsg((HyperCR0 & (X86_CR0_TS | X86_CR0_MP)) == (X86_CR0_TS | X86_CR0_MP), ("%#x\n", HyperCR0));
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
*puValue = 0;
switch (idMsr)
case MSR_IA32_TSC:
case MSR_IA32_APICBASE:
*puValue = 0;
case MSR_IA32_CR_PAT:
case MSR_IA32_SYSENTER_CS:
case MSR_IA32_SYSENTER_EIP:
case MSR_IA32_SYSENTER_ESP:
case MSR_IA32_MTRR_CAP:
bool const fSystemManagementRangeRegisters = false;
bool const fFixedRangeRegisters = false;
bool const fWriteCombiningType = false;
case MSR_IA32_MTRR_DEF_TYPE:
case IA32_MTRR_FIX64K_00000:
case IA32_MTRR_FIX16K_80000:
case IA32_MTRR_FIX16K_A0000:
case IA32_MTRR_FIX4K_C0000:
case IA32_MTRR_FIX4K_C8000:
case IA32_MTRR_FIX4K_D0000:
case IA32_MTRR_FIX4K_D8000:
case IA32_MTRR_FIX4K_E0000:
case IA32_MTRR_FIX4K_E8000:
case IA32_MTRR_FIX4K_F0000:
case IA32_MTRR_FIX4K_F8000:
case MSR_K6_EFER:
case MSR_K8_SF_MASK:
case MSR_K6_STAR:
case MSR_K8_LSTAR:
case MSR_K8_CSTAR:
case MSR_K8_FS_BASE:
case MSR_K8_GS_BASE:
case MSR_K8_KERNEL_GS_BASE:
case MSR_K8_TSC_AUX:
case MSR_IA32_PERF_STATUS:
case MSR_IA32_FSB_CLOCK_STS:
case MSR_IA32_PLATFORM_INFO:
case MSR_IA32_THERM_STATUS:
case MSR_IA32_MISC_ENABLE:
case MSR_IA32_PLATFORM_ID:
case MSR_IA32_BIOS_SIGN_ID:
*puValue = 0;
*puValue = 0;
return rc;
switch (idMsr)
case MSR_IA32_MISC_ENABLE:
case MSR_IA32_TSC:
case MSR_IA32_APICBASE:
case MSR_IA32_CR_PAT:
case MSR_IA32_SYSENTER_CS:
case MSR_IA32_SYSENTER_EIP:
case MSR_IA32_SYSENTER_ESP:
case MSR_IA32_MTRR_CAP:
return VERR_CPUM_RAISE_GP_0;
case MSR_IA32_MTRR_DEF_TYPE:
return VERR_CPUM_RAISE_GP_0;
case IA32_MTRR_FIX64K_00000:
case IA32_MTRR_FIX16K_80000:
case IA32_MTRR_FIX16K_A0000:
case IA32_MTRR_FIX4K_C0000:
case IA32_MTRR_FIX4K_C8000:
case IA32_MTRR_FIX4K_D0000:
case IA32_MTRR_FIX4K_D8000:
case IA32_MTRR_FIX4K_E0000:
case IA32_MTRR_FIX4K_E8000:
case IA32_MTRR_FIX4K_F0000:
case IA32_MTRR_FIX4K_F8000:
case MSR_K6_EFER:
return VERR_CPUM_RAISE_GP_0;
AssertMsg(!(uValue & ~(MSR_K6_EFER_NXE | MSR_K6_EFER_LME | MSR_K6_EFER_LMA /* ignored anyway */ | MSR_K6_EFER_SCE | MSR_K6_EFER_FFXSR)),
case MSR_K8_SF_MASK:
case MSR_K6_STAR:
case MSR_K8_LSTAR:
case MSR_K8_CSTAR:
case MSR_K8_FS_BASE:
case MSR_K8_GS_BASE:
case MSR_K8_KERNEL_GS_BASE:
case MSR_K8_TSC_AUX:
return rc;
if (pcbLimit)
if (pHidden)
u64 = 0;
return u64;
switch (iReg)
case DISCREG_CR0:
case DISCREG_CR2:
case DISCREG_CR3:
case DISCREG_CR4:
case DISCREG_CR8:
*pValue = 0;
return rc;
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
return VINF_SUCCESS;
VMMDECL(void) CPUMGetGuestCpuId(PVMCPU pVCpu, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
pCpuId = &pVM->cpum.s.aGuestCpuIdHyper[iLeaf - UINT32_C(0x40000000)]; /* Only report if HVP bit set. */
switch (cCurrentCacheIndex)
AssertFailed();
Log2(("CPUMGetGuestCpuId: iLeaf=%#010x %RX32 %RX32 %RX32 %RX32\n", iLeaf, *pEax, *pEbx, *pEcx, *pEdx));
switch (enmFeature)
case CPUMCPUIDFEATURE_APIC:
case CPUMCPUIDFEATURE_X2APIC:
case CPUMCPUIDFEATURE_SEP:
case CPUMCPUIDFEATURE_SYSCALL:
case CPUMCPUIDFEATURE_PAE:
case CPUMCPUIDFEATURE_NXE:
case CPUMCPUIDFEATURE_LAHF:
case CPUMCPUIDFEATURE_PAT:
case CPUMCPUIDFEATURE_RDTSCP:
case CPUMCPUIDFEATURE_HVP:
switch (enmFeature)
case CPUMCPUIDFEATURE_PAE:
case CPUMCPUIDFEATURE_NXE:
case CPUMCPUIDFEATURE_RDTSCP:
switch (enmFeature)
case CPUMCPUIDFEATURE_APIC:
case CPUMCPUIDFEATURE_X2APIC:
case CPUMCPUIDFEATURE_PAE:
case CPUMCPUIDFEATURE_PAT:
case CPUMCPUIDFEATURE_LAHF:
case CPUMCPUIDFEATURE_HVP:
#ifdef CPUM_VIRTUALIZE_DRX
#ifdef IN_RC
#ifdef IN_RC
return VINF_SUCCESS;
#ifndef IN_RING0
#ifdef IN_RING0
#ifndef IN_RING3
return fRc;
#ifndef IN_RING0
cpl = 0;
return cpl;
return enmMode;