VMMSwitcher.cpp revision 5e0d5717f4742e9fc86690c4406e0af249336bbf
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * VMM - The Virtual Machine Monitor, World Switcher(s).
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * available from http://www.virtualbox.org. This file is free software;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * you can redistribute it and/or modify it under the terms of the GNU
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * General Public License (GPL) as published by the Free Software
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * additional information or have any questions.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/*******************************************************************************
59190ecd61435d19ba3515b876272aee7bd12298vboxsync* Header Files *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync*******************************************************************************/
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/*******************************************************************************
59190ecd61435d19ba3515b876272aee7bd12298vboxsync* Global Variables *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync*******************************************************************************/
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/** Array of switcher defininitions.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * The type and index shall match!
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncstatic PVMMSWITCHERDEF s_apSwitchers[VMMSWITCHER_MAX] =
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#else /* RT_ARCH_AMD64 */
unsigned cbCoreCode = 0;
if (pSwitcher)
pVM->vmm.s.pvCoreCodeR3 = SUPR3ContAlloc(pVM->vmm.s.cbCoreCode >> PAGE_SHIFT, &pVM->vmm.s.pvCoreCodeR0, &pVM->vmm.s.HCPhysCoreCode);
struct VMMInitBadTry
void *pvR3;
pVM->vmm.s.pvCoreCodeR3 = SUPR3ContAlloc(pVM->vmm.s.cbCoreCode >> PAGE_SHIFT, &pVM->vmm.s.pvCoreCodeR0, &pVM->vmm.s.HCPhysCoreCode);
if (pSwitcher)
rc = MMR3HyperMapHCPhys(pVM, pVM->vmm.s.pvCoreCodeR3, pVM->vmm.s.pvCoreCodeR0, pVM->vmm.s.HCPhysCoreCode,
pVM->vmm.s.pvCoreCodeR3, pVM->vmm.s.pvCoreCodeR0, pVM->vmm.s.pvCoreCodeRC, pVM->vmm.s.HCPhysCoreCode, pVM->vmm.s.cbCoreCode));
return rc;
AssertMsgFailed(("PGMR3Map(,%RRv, %RHp, %#x, 0) failed with rc=%Rrc\n", pVM->vmm.s.pvCoreCodeRC, pVM->vmm.s.HCPhysCoreCode, cbCoreCode, rc));
return rc;
static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode,
const void *pv;
uintptr_t u;
uintptr_t u;
} uSrc;
switch (u8)
case FIX_HC_2_GC_NEAR_REL:
Assert(offSrc - pSwitcher->offHCCode0 < pSwitcher->cbHCCode0 || offSrc - pSwitcher->offHCCode1 < pSwitcher->cbHCCode1);
case FIX_HC_2_ID_NEAR_REL:
Assert(offSrc - pSwitcher->offHCCode0 < pSwitcher->cbHCCode0 || offSrc - pSwitcher->offHCCode1 < pSwitcher->cbHCCode1);
Assert(offTrg - pSwitcher->offIDCode0 < pSwitcher->cbIDCode0 || offTrg - pSwitcher->offIDCode1 < pSwitcher->cbIDCode1);
case FIX_GC_2_HC_NEAR_REL:
Assert(offTrg - pSwitcher->offHCCode0 < pSwitcher->cbHCCode0 || offTrg - pSwitcher->offHCCode1 < pSwitcher->cbHCCode1);
case FIX_GC_2_ID_NEAR_REL:
AssertMsg(offSrc - pSwitcher->offGCCode < pSwitcher->cbGCCode, ("%x - %x < %x\n", offSrc, pSwitcher->offGCCode, pSwitcher->cbGCCode));
Assert(offTrg - pSwitcher->offIDCode0 < pSwitcher->cbIDCode0 || offTrg - pSwitcher->offIDCode1 < pSwitcher->cbIDCode1);
case FIX_ID_2_HC_NEAR_REL:
Assert(offSrc - pSwitcher->offIDCode0 < pSwitcher->cbIDCode0 || offSrc - pSwitcher->offIDCode1 < pSwitcher->cbIDCode1);
Assert(offTrg - pSwitcher->offHCCode0 < pSwitcher->cbHCCode0 || offTrg - pSwitcher->offHCCode1 < pSwitcher->cbHCCode1);
case FIX_ID_2_GC_NEAR_REL:
Assert(offSrc - pSwitcher->offIDCode0 < pSwitcher->cbIDCode0 || offSrc - pSwitcher->offIDCode1 < pSwitcher->cbIDCode1);
case FIX_GC_FAR32:
case FIX_GC_CPUM_OFF:
case FIX_GC_CPUMCPU_OFF:
case FIX_GC_VM_OFF:
case FIX_HC_CPUM_OFF:
case FIX_HC_VM_OFF:
case FIX_INTER_32BIT_CR3:
case FIX_INTER_PAE_CR3:
case FIX_INTER_AMD64_CR3:
case FIX_HYPER_CS:
case FIX_HYPER_DS:
case FIX_HYPER_TSS:
case FIX_GC_TSS_GDTE_DW2:
case FIX_NO_FXSAVE_JMP:
case FIX_NO_SYSENTER_JMP:
case FIX_NO_SYSCALL_JMP:
case FIX_HC_32BIT:
Assert(offTrg - pSwitcher->offHCCode0 < pSwitcher->cbHCCode0 || offTrg - pSwitcher->offHCCode1 < pSwitcher->cbHCCode1);
case FIX_HC_64BIT_CS:
case FIX_HC_64BIT_CPUM:
case FIX_HC_64BIT:
Assert(offTrg - pSwitcher->offHCCode0 < pSwitcher->cbHCCode0 || offTrg - pSwitcher->offHCCode1 < pSwitcher->cbHCCode1);
#ifdef RT_ARCH_X86
case FIX_GC_64_BIT_CPUM_OFF:
case FIX_ID_32BIT:
Assert(offTrg - pSwitcher->offIDCode0 < pSwitcher->cbIDCode0 || offTrg - pSwitcher->offIDCode1 < pSwitcher->cbIDCode1);
case FIX_ID_64BIT:
case FIX_HC_64BIT_NOCHECK:
Assert(u8 == FIX_HC_64BIT_NOCHECK || offTrg - pSwitcher->offIDCode0 < pSwitcher->cbIDCode0 || offTrg - pSwitcher->offIDCode1 < pSwitcher->cbIDCode1);
Assert(offTrg - pSwitcher->offIDCode0 < pSwitcher->cbIDCode0 || offTrg - pSwitcher->offIDCode1 < pSwitcher->cbIDCode1);
#ifdef VBOX_WITH_NMI
case FIX_GC_APIC_BASE_32BIT:
#ifdef LOG_ENABLED
if (LogIs2Enabled())
pVM,
offCode++;
while (cbCode > 0)
if (RT_SUCCESS(DISInstr(&Cpu, (RTUINTPTR)pu8CodeR3 + offCode, uBase - (RTUINTPTR)pu8CodeR3, &cbInstr, szDisas)))
DECLCALLBACK(void) vmmR3Switcher32BitTo32Bit_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode)
DECLCALLBACK(void) vmmR3Switcher32BitToPAE_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode)
DECLCALLBACK(void) vmmR3Switcher32BitToAMD64_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode)
SELMGetHyperCS(pVM), SELMGetHyperDS(pVM), SELMGetHyperTSS(pVM), SELMGetHyperGDT(pVM), SELMGetHyperCS64(pVM));
DECLCALLBACK(void) vmmR3SwitcherPAETo32Bit_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode)
DECLCALLBACK(void) vmmR3SwitcherPAEToPAE_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode)
DECLCALLBACK(void) vmmR3SwitcherPAEToAMD64_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode)
SELMGetHyperCS(pVM), SELMGetHyperDS(pVM), SELMGetHyperTSS(pVM), SELMGetHyperGDT(pVM), SELMGetHyperCS64(pVM));
DECLCALLBACK(void) vmmR3SwitcherAMD64To32Bit_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode)
SELMGetHyperCS(pVM), SELMGetHyperDS(pVM), SELMGetHyperTSS(pVM), SELMGetHyperGDT(pVM), SELMGetHyperCS64(pVM));
DECLCALLBACK(void) vmmR3SwitcherAMD64ToPAE_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode)
SELMGetHyperCS(pVM), SELMGetHyperDS(pVM), SELMGetHyperTSS(pVM), SELMGetHyperGDT(pVM), SELMGetHyperCS64(pVM));
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
if (pSwitcher)
Log(("VMMR3SelectSwitcher: enmSwitcher %d -> %d %s\n", pVM->vmm.s.enmSwitcher, enmSwitcher, pSwitcher->pszDesc));
RTR0PTR pbCodeR0 = (RTR0PTR)pVM->vmm.s.pvCoreCodeR0 + pVM->vmm.s.aoffSwitchers[enmSwitcher]; /** @todo fix the pvCoreCodeR0 type */
return VINF_SUCCESS;
return VERR_NOT_IMPLEMENTED;
* And then check for fSwitcherDisabled in VMMR3SelectSwitcher() in order to prevent it from being removed.
return VINF_SUCCESS;
return NIL_RTR0PTR;
if (pSwitcher)
RTR0PTR pbCodeR0 = (RTR0PTR)pVM->vmm.s.pvCoreCodeR0 + pVM->vmm.s.aoffSwitchers[enmSwitcher]; /** @todo fix the pvCoreCodeR0 type */
return NIL_RTR0PTR;