CPUMAllRegs.cpp revision 6a0b07769eda54d23301f8b192ec02094a3667b1
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * CPUM - CPU Monitor(/Manager) - Gets and Sets.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Copyright (C) 2006-2007 innotek GmbH
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * available from http://www.virtualbox.org. This file is free software;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * General Public License (GPL) as published by the Free Software
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/*******************************************************************************
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync* Header Files *
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync*******************************************************************************/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/** Disable stack frame pointer generation here. */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Sets or resets an alternative hypervisor context core.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * This is called when we get a hypervisor trap set switch the context
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * core with the trap frame on the stack. It is called again to reset
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * back to the default context core when resuming hypervisor execution.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * @param pVM The VM handle.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * @param pCtxCore Pointer to the alternative context core or NULL
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * to go back to the default context core.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncCPUMDECL(void) CPUMHyperSetCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync LogFlow(("CPUMHyperSetCtxCore: %p/%p/%p -> %p\n", pVM->cpum.s.CTXALLSUFF(pHyperCore), pCtxCore));
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync pVM->cpum.s.pHyperCoreR3 = (R3PTRTYPE(PCPUMCTXCORE))VM_R3_ADDR(pVM, pCtxCore);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync pVM->cpum.s.pHyperCoreR0 = (R0PTRTYPE(PCPUMCTXCORE))VM_R0_ADDR(pVM, pCtxCore);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync pVM->cpum.s.pHyperCoreGC = (GCPTRTYPE(PCPUMCTXCORE))VM_GUEST_ADDR(pVM, pCtxCore);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync pVM->cpum.s.pHyperCoreR3 = (R3PTRTYPE(PCPUMCTXCORE))MMHyperCCToR3(pVM, pCtxCore);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync pVM->cpum.s.pHyperCoreR0 = (R0PTRTYPE(PCPUMCTXCORE))MMHyperCCToR0(pVM, pCtxCore);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync pVM->cpum.s.pHyperCoreGC = (GCPTRTYPE(PCPUMCTXCORE))MMHyperCCToGC(pVM, pCtxCore);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * Gets the pointer to the internal CPUMCTXCORE structure for the hypervisor.
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * This is only for reading in order to save a few calls.
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * @param pVM Handle to the virtual machine.
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncCPUMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVM pVM)
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * Queries the pointer to the internal CPUMCTX structure for the hypervisor.
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * @returns VBox status code.
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * @param pVM Handle to the virtual machine.
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * @param ppCtx Receives the hyper CPUMCTX pointer when successful.
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * @deprecated This will *not* (and has never) given the right picture of the
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * hypervisor register state. With CPUMHyperSetCtxCore() this is
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * getting much worse. So, use the individual functions for getting
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * and esp. setting the hypervisor registers.
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncCPUMDECL(int) CPUMQueryHyperCtxPtr(PVM pVM, PCPUMCTX *ppCtx)
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncCPUMDECL(void) CPUMSetHyperGDTR(PVM pVM, uint32_t addr, uint16_t limit)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncCPUMDECL(void) CPUMSetHyperIDTR(PVM pVM, uint32_t addr, uint16_t limit)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncCPUMDECL(void) CPUMSetHyperCR3(PVM pVM, uint32_t cr3)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncCPUMDECL(void) CPUMSetHyperESP(PVM pVM, uint32_t u32ESP)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncCPUMDECL(int) CPUMSetHyperEFlags(PVM pVM, uint32_t Efl)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync pVM->cpum.s.CTXALLSUFF(pHyperCore)->eflags.u32 = Efl;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncCPUMDECL(void) CPUMSetHyperEIP(PVM pVM, uint32_t u32EIP)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncCPUMDECL(void) CPUMSetHyperLDTR(PVM pVM, RTSEL SelLDTR)
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncCPUMDECL(void) CPUMSetHyperDR0(PVM pVM, RTGCUINTREG uDr0)
a2544ef163bb615c50680a75e0958e2eb801727avboxsync /** @todo in GC we must load it! */
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncCPUMDECL(void) CPUMSetHyperDR1(PVM pVM, RTGCUINTREG uDr1)
a2544ef163bb615c50680a75e0958e2eb801727avboxsync /** @todo in GC we must load it! */
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncCPUMDECL(void) CPUMSetHyperDR2(PVM pVM, RTGCUINTREG uDr2)
a2544ef163bb615c50680a75e0958e2eb801727avboxsync /** @todo in GC we must load it! */
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncCPUMDECL(void) CPUMSetHyperDR3(PVM pVM, RTGCUINTREG uDr3)
a2544ef163bb615c50680a75e0958e2eb801727avboxsync /** @todo in GC we must load it! */
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncCPUMDECL(void) CPUMSetHyperDR6(PVM pVM, RTGCUINTREG uDr6)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync /** @todo in GC we must load it! */
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncCPUMDECL(void) CPUMSetHyperDR7(PVM pVM, RTGCUINTREG uDr7)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /** @todo in GC we must load it! */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync#if 0 /* these are not correct. */
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync#endif /* not correct */
if (pcbLimit)
if (pcbLimit)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifdef IN_GC
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;
if (pcbLimit)
switch (iReg)
case USE_REG_CR0:
case USE_REG_CR2:
case USE_REG_CR3:
case USE_REG_CR4:
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
switch (iReg)
case USE_REG_DR0:
case USE_REG_DR1:
case USE_REG_DR2:
case USE_REG_DR3:
case USE_REG_DR4:
case USE_REG_DR6:
case USE_REG_DR5:
case USE_REG_DR7:
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
CPUMDECL(void) CPUMGetGuestCpuId(PVM pVM, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
Log2(("CPUMGetGuestCpuId: iLeaf=%#010x %RX32 %RX32 %RX32 %RX32\n", iLeaf, *pEax, *pEbx, *pEcx, *pEdx));
switch (enmFeature)
case CPUMCPUIDFEATURE_APIC:
case CPUMCPUIDFEATURE_SEP:
case CPUMCPUIDFEATURE_PAE:
switch (enmFeature)
case CPUMCPUIDFEATURE_APIC:
switch (iReg)
case USE_REG_DR0:
case USE_REG_DR1:
case USE_REG_DR2:
case USE_REG_DR3:
case USE_REG_DR4:
case USE_REG_DR6:
case USE_REG_DR5:
case USE_REG_DR7:
return VERR_INVALID_PARAMETER;
#ifdef CPUM_VIRTUALIZE_DRX
#ifdef IN_GC
#ifdef IN_GC
return VINF_SUCCESS;
if (!pCtxCore)
Assert((pVM->cpum.s.Guest.cr0 & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) == (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP));
return VINF_SUCCESS;
return rc;
if (!pCtxCore)
AssertMsg(pCtxCore->eflags.Bits.u1VM || pCtxCore->eflags.Bits.u2IOPL < (unsigned)(pCtxCore->ss & X86_SEL_RPL),
return rc;
#ifdef IN_RING0
return fFlags;
#ifndef IN_RING3
#ifndef IN_RING0
cpl = 0;
return cpl;
else //GUEST64 if (!(pVM->cpum.s.Guest.efer & MSR_K6_EFER_LMA)
return enmMode;