diff options
| author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
|---|---|---|
| committer | <> | 2014-05-08 15:03:54 +0000 |
| commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
| tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/VMMR3/VMMSwitcher.cpp | |
| parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
| download | VirtualBox-master.tar.gz | |
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/VMM/VMMR3/VMMSwitcher.cpp')
| -rw-r--r-- | src/VBox/VMM/VMMR3/VMMSwitcher.cpp | 287 |
1 files changed, 216 insertions, 71 deletions
diff --git a/src/VBox/VMM/VMMR3/VMMSwitcher.cpp b/src/VBox/VMM/VMMR3/VMMSwitcher.cpp index 301f4e42..f6aa164e 100644 --- a/src/VBox/VMM/VMMR3/VMMSwitcher.cpp +++ b/src/VBox/VMM/VMMR3/VMMSwitcher.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -15,12 +15,14 @@ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ + /******************************************************************************* * Header Files * *******************************************************************************/ #define LOG_GROUP LOG_GROUP_VMM #include <VBox/vmm/vmm.h> #include <VBox/vmm/pgm.h> +#include <VBox/vmm/hm.h> #include <VBox/vmm/selm.h> #include <VBox/vmm/mm.h> #include <VBox/sup.h> @@ -45,24 +47,24 @@ /** Array of switcher definitions. * The type and index shall match! */ -static PVMMSWITCHERDEF s_apSwitchers[VMMSWITCHER_MAX] = +static PVMMSWITCHERDEF g_apRawModeSwitchers[VMMSWITCHER_MAX] = { NULL, /* invalid entry */ #ifdef VBOX_WITH_RAW_MODE # ifndef RT_ARCH_AMD64 &vmmR3Switcher32BitTo32Bit_Def, &vmmR3Switcher32BitToPAE_Def, - &vmmR3Switcher32BitToAMD64_Def, + NULL, //&vmmR3Switcher32BitToAMD64_Def, &vmmR3SwitcherPAETo32Bit_Def, &vmmR3SwitcherPAEToPAE_Def, - &vmmR3SwitcherPAEToAMD64_Def, + NULL, //&vmmR3SwitcherPAEToAMD64_Def, NULL, //&vmmR3SwitcherPAETo32Bit_Def, # ifdef VBOX_WITH_HYBRID_32BIT_KERNEL &vmmR3SwitcherAMD64ToPAE_Def, # else NULL, //&vmmR3SwitcherAMD64ToPAE_Def, # endif - NULL //&vmmR3SwitcherAMD64ToAMD64_Def, + NULL, //&vmmR3SwitcherAMD64ToAMD64_Def, # else /* RT_ARCH_AMD64 */ NULL, //&vmmR3Switcher32BitTo32Bit_Def, NULL, //&vmmR3Switcher32BitToPAE_Def, @@ -72,7 +74,7 @@ static PVMMSWITCHERDEF s_apSwitchers[VMMSWITCHER_MAX] = NULL, //&vmmR3SwitcherPAEToAMD64_Def, &vmmR3SwitcherAMD64To32Bit_Def, &vmmR3SwitcherAMD64ToPAE_Def, - NULL //&vmmR3SwitcherAMD64ToAMD64_Def, + NULL, //&vmmR3SwitcherAMD64ToAMD64_Def, # endif /* RT_ARCH_AMD64 */ #else /* !VBOX_WITH_RAW_MODE */ NULL, @@ -83,11 +85,126 @@ static PVMMSWITCHERDEF s_apSwitchers[VMMSWITCHER_MAX] = NULL, NULL, NULL, - NULL + NULL, +#endif /* !VBOX_WITH_RAW_MODE */ +#ifndef RT_ARCH_AMD64 + &vmmR3SwitcherX86Stub_Def, + NULL, +#else + NULL, + &vmmR3SwitcherAMD64Stub_Def, +#endif +}; + +/** Array of switcher definitions. + * The type and index shall match! + */ +static PVMMSWITCHERDEF g_apHmSwitchers[VMMSWITCHER_MAX] = +{ + NULL, /* invalid entry */ +#if HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL) + NULL, //&vmmR3Switcher32BitTo32Bit_Def, + NULL, //&vmmR3Switcher32BitToPAE_Def, + &vmmR3Switcher32BitToAMD64_Def, + NULL, //&vmmR3SwitcherPAETo32Bit_Def, + NULL, //&vmmR3SwitcherPAEToPAE_Def, + &vmmR3SwitcherPAEToAMD64_Def, + NULL, //&vmmR3SwitcherPAETo32Bit_Def, + NULL, //&vmmR3SwitcherAMD64ToPAE_Def, + NULL, //&vmmR3SwitcherAMD64ToAMD64_Def, +#else /* !VBOX_WITH_RAW_MODE */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, #endif /* !VBOX_WITH_RAW_MODE */ +#ifndef RT_ARCH_AMD64 + &vmmR3SwitcherX86Stub_Def, + NULL, +#else + NULL, + &vmmR3SwitcherAMD64Stub_Def, +#endif }; +# ifdef VBOX_WITH_64ON32_IDT +/** + * Initializes the 64-bit IDT for 64-bit guest on 32-bit host switchers. + * + * This is only used as a debugging aid when we cannot find out why something + * goes haywire in the intermediate context. + * + * @param pVM The cross context VM structure. + * @param pSwitcher The switcher descriptor. + * @param pbDst Where the switcher code was just copied. + * @param HCPhysDst The host physical address corresponding to @a pbDst. + */ +static void vmmR3Switcher32On64IdtInit(PVM pVM, PVMMSWITCHERDEF pSwitcher, uint8_t *pbDst, RTHCPHYS HCPhysDst) +{ + AssertRelease(pSwitcher->offGCCode > 0 && pSwitcher->offGCCode < pSwitcher->cbCode); + AssertRelease(pSwitcher->cbCode < _64K); + RTSEL uCs64 = SELMGetHyperCS64(pVM); + + PX86DESC64GATE paIdt = (PX86DESC64GATE)(pbDst + pSwitcher->offGCCode); + for (uint32_t i = 0 ; i < 256; i++) + { + AssertRelease(((uint64_t *)&paIdt[i])[0] < pSwitcher->cbCode); + AssertRelease(((uint64_t *)&paIdt[i])[1] == 0); + uint64_t uHandler = HCPhysDst + paIdt[i].u16OffsetLow; + paIdt[i].u16OffsetLow = (uint16_t)uHandler; + paIdt[i].u16Sel = uCs64; + paIdt[i].u3IST = 0; + paIdt[i].u5Reserved = 0; + paIdt[i].u4Type = AMD64_SEL_TYPE_SYS_INT_GATE; + paIdt[i].u1DescType = 0 /* system */; + paIdt[i].u2Dpl = 3; + paIdt[i].u1Present = 1; + paIdt[i].u16OffsetHigh = (uint16_t)(uHandler >> 16); + paIdt[i].u32Reserved = (uint32_t)(uHandler >> 32); + } + + for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++) + { + uint64_t uIdtr = HCPhysDst + pSwitcher->offGCCode; AssertRelease(uIdtr < UINT32_MAX); + CPUMSetHyperIDTR(&pVM->aCpus[iCpu], uIdtr, 16*256 + iCpu); + } +} + + +/** + * Relocates the 64-bit IDT for 64-bit guest on 32-bit host switchers. + * + * @param pVM The cross context VM structure. + * @param pSwitcher The switcher descriptor. + * @param pbDst Where the switcher code was just copied. + * @param HCPhysDst The host physical address corresponding to @a pbDst. + */ +static void vmmR3Switcher32On64IdtRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, uint8_t *pbDst, RTHCPHYS HCPhysDst) +{ + AssertRelease(pSwitcher->offGCCode > 0 && pSwitcher->offGCCode < pSwitcher->cbCode && pSwitcher->cbCode < _64K); + + /* The intermediate context doesn't move, but the CS may. */ + RTSEL uCs64 = SELMGetHyperCS64(pVM); + PX86DESC64GATE paIdt = (PX86DESC64GATE)(pbDst + pSwitcher->offGCCode); + for (uint32_t i = 0 ; i < 256; i++) + paIdt[i].u16Sel = uCs64; + + /* Just in case... */ + for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++) + { + uint64_t uIdtr = HCPhysDst + pSwitcher->offGCCode; AssertRelease(uIdtr < UINT32_MAX); + CPUMSetHyperIDTR(&pVM->aCpus[iCpu], uIdtr, 16*256 + iCpu); + } +} +# endif /* VBOX_WITH_64ON32_IDT */ + + /** * VMMR3Init worker that initiates the switcher code (aka core code). * @@ -99,17 +216,19 @@ static PVMMSWITCHERDEF s_apSwitchers[VMMSWITCHER_MAX] = */ int vmmR3SwitcherInit(PVM pVM) { -#ifndef VBOX_WITH_RAW_MODE +#if !defined(VBOX_WITH_RAW_MODE) && (HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)) return VINF_SUCCESS; #else + /* * Calc the size. */ + const PVMMSWITCHERDEF *papSwitchers = HMIsEnabled(pVM) ? g_apHmSwitchers : g_apRawModeSwitchers; unsigned cbCoreCode = 0; - for (unsigned iSwitcher = 0; iSwitcher < RT_ELEMENTS(s_apSwitchers); iSwitcher++) + for (unsigned iSwitcher = 0; iSwitcher < VMMSWITCHER_MAX; iSwitcher++) { pVM->vmm.s.aoffSwitchers[iSwitcher] = cbCoreCode; - PVMMSWITCHERDEF pSwitcher = s_apSwitchers[iSwitcher]; + PVMMSWITCHERDEF pSwitcher = papSwitchers[iSwitcher]; if (pSwitcher) { AssertRelease((unsigned)pSwitcher->enmType == iSwitcher); @@ -177,14 +296,22 @@ int vmmR3SwitcherInit(PVM pVM) if (RT_SUCCESS(rc)) { /* - * copy the code. + * Copy the code. */ - for (unsigned iSwitcher = 0; iSwitcher < RT_ELEMENTS(s_apSwitchers); iSwitcher++) + for (unsigned iSwitcher = 0; iSwitcher < VMMSWITCHER_MAX; iSwitcher++) { - PVMMSWITCHERDEF pSwitcher = s_apSwitchers[iSwitcher]; + PVMMSWITCHERDEF pSwitcher = papSwitchers[iSwitcher]; if (pSwitcher) - memcpy((uint8_t *)pVM->vmm.s.pvCoreCodeR3 + pVM->vmm.s.aoffSwitchers[iSwitcher], - pSwitcher->pvCode, pSwitcher->cbCode); + { + uint8_t *pbDst = (uint8_t *)pVM->vmm.s.pvCoreCodeR3 + pVM->vmm.s.aoffSwitchers[iSwitcher]; + memcpy(pbDst, pSwitcher->pvCode, pSwitcher->cbCode); +# ifdef VBOX_WITH_64ON32_IDT + if ( pSwitcher->enmType == VMMSWITCHER_32_TO_AMD64 + || pSwitcher->enmType == VMMSWITCHER_PAE_TO_AMD64) + vmmR3Switcher32On64IdtInit(pVM, pSwitcher, pbDst, + pVM->vmm.s.HCPhysCoreCode + pVM->vmm.s.aoffSwitchers[iSwitcher]); +# endif + } } /* @@ -204,6 +331,7 @@ int vmmR3SwitcherInit(PVM pVM) * Finally, PGM probably has selected a switcher already but we need * to get the routine addresses, so we'll reselect it. * This may legally fail so, we're ignoring the rc. + * Note! See HMIsEnabled hack in selector function. */ VMMR3SelectSwitcher(pVM, pVM->vmm.s.enmSwitcher); return rc; @@ -233,13 +361,14 @@ int vmmR3SwitcherInit(PVM pVM) */ void vmmR3SwitcherRelocate(PVM pVM, RTGCINTPTR offDelta) { -#ifdef VBOX_WITH_RAW_MODE +#if defined(VBOX_WITH_RAW_MODE) || (HC_ARCH_BITS != 64 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)) /* * Relocate all the switchers. */ - for (unsigned iSwitcher = 0; iSwitcher < RT_ELEMENTS(s_apSwitchers); iSwitcher++) + const PVMMSWITCHERDEF *papSwitchers = HMIsEnabled(pVM) ? g_apHmSwitchers : g_apRawModeSwitchers; + for (unsigned iSwitcher = 0; iSwitcher < VMMSWITCHER_MAX; iSwitcher++) { - PVMMSWITCHERDEF pSwitcher = s_apSwitchers[iSwitcher]; + PVMMSWITCHERDEF pSwitcher = papSwitchers[iSwitcher]; if (pSwitcher && pSwitcher->pfnRelocate) { unsigned off = pVM->vmm.s.aoffSwitchers[iSwitcher]; @@ -249,20 +378,31 @@ void vmmR3SwitcherRelocate(PVM pVM, RTGCINTPTR offDelta) (uint8_t *)pVM->vmm.s.pvCoreCodeR3 + off, pVM->vmm.s.pvCoreCodeRC + off, pVM->vmm.s.HCPhysCoreCode + off); +# ifdef VBOX_WITH_64ON32_IDT + if ( pSwitcher->enmType == VMMSWITCHER_32_TO_AMD64 + || pSwitcher->enmType == VMMSWITCHER_PAE_TO_AMD64) + vmmR3Switcher32On64IdtRelocate(pVM, pSwitcher, + (uint8_t *)pVM->vmm.s.pvCoreCodeR3 + off, + pVM->vmm.s.HCPhysCoreCode + off); +# endif } } /* * Recalc the RC address for the current switcher. */ - PVMMSWITCHERDEF pSwitcher = s_apSwitchers[pVM->vmm.s.enmSwitcher]; - RTRCPTR RCPtr = pVM->vmm.s.pvCoreCodeRC + pVM->vmm.s.aoffSwitchers[pVM->vmm.s.enmSwitcher]; - pVM->vmm.s.pfnRCToHost = RCPtr + pSwitcher->offRCToHost; - pVM->vmm.s.pfnCallTrampolineRC = RCPtr + pSwitcher->offRCCallTrampoline; - pVM->pfnVMMRCToHostAsm = RCPtr + pSwitcher->offRCToHostAsm; - pVM->pfnVMMRCToHostAsmNoReturn = RCPtr + pSwitcher->offRCToHostAsmNoReturn; - -// AssertFailed(); + PVMMSWITCHERDEF pSwitcher = papSwitchers[pVM->vmm.s.enmSwitcher]; + if (pSwitcher) + { + RTRCPTR RCPtr = pVM->vmm.s.pvCoreCodeRC + pVM->vmm.s.aoffSwitchers[pVM->vmm.s.enmSwitcher]; + pVM->vmm.s.pfnRCToHost = RCPtr + pSwitcher->offRCToHost; + pVM->vmm.s.pfnCallTrampolineRC = RCPtr + pSwitcher->offRCCallTrampoline; + pVM->pfnVMMRCToHostAsm = RCPtr + pSwitcher->offRCToHostAsm; + pVM->pfnVMMRCToHostAsmNoReturn = RCPtr + pSwitcher->offRCToHostAsmNoReturn; + } + else + AssertRelease(HMIsEnabled(pVM)); + #else NOREF(pVM); #endif @@ -270,6 +410,8 @@ void vmmR3SwitcherRelocate(PVM pVM, RTGCINTPTR offDelta) } +#if defined(VBOX_WITH_RAW_MODE) || (HC_ARCH_BITS != 64 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)) + /** * Generic switcher code relocator. * @@ -285,7 +427,8 @@ void vmmR3SwitcherRelocate(PVM pVM, RTGCINTPTR offDelta) * @param GCPtrGDT The GC address of the hypervisor GDT. * @param SelCS64 The 64-bit mode hypervisor CS selector. */ -static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode, +static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, + RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode, RTSEL SelCS, RTSEL SelDS, RTSEL SelTSS, RTGCPTR GCPtrGDT, RTSEL SelCS64) { union @@ -618,18 +761,18 @@ static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR break; } -#if defined(RT_ARCH_AMD64) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +# if defined(RT_ARCH_AMD64) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) /* * 64-bit HC Code Selector (no argument). */ case FIX_HC_64BIT_CS: { Assert(offSrc < pSwitcher->cbCode); -# if defined(RT_OS_DARWIN) && defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +# if defined(RT_OS_DARWIN) && defined(VBOX_WITH_HYBRID_32BIT_KERNEL) *uSrc.pu16 = 0x80; /* KERNEL64_CS from i386/seg.h */ -# else +# else AssertFatalMsgFailed(("FIX_HC_64BIT_CS not implemented for this host\n")); -# endif +# endif break; } @@ -642,7 +785,7 @@ static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR *uSrc.pu64 = pVM->pVMR0 + RT_OFFSETOF(VM, cpum); break; } -#endif +# endif /* * 64-bit HC pointer fixup to (HC) target within the code (32-bit offset). */ @@ -655,7 +798,7 @@ static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR break; } -#ifdef RT_ARCH_X86 +# ifdef RT_ARCH_X86 case FIX_GC_64_BIT_CPUM_OFF: { uint32_t offCPUM = *u.pu32++; @@ -663,7 +806,7 @@ static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR *uSrc.pu64 = (uint32_t)(VM_RC_ADDR(pVM, &pVM->cpum) + offCPUM); break; } -#endif +# endif /* * 32-bit ID pointer to (ID) target within the code (32-bit offset). @@ -704,7 +847,7 @@ static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR break; } -#ifdef VBOX_WITH_NMI +# ifdef VBOX_WITH_NMI /* * 32-bit address to the APIC base. */ @@ -713,7 +856,7 @@ static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR *uSrc.pu32 = pVM->vmm.s.GCPtrApicBase; break; } -#endif +# endif default: AssertReleaseMsgFailed(("Unknown fixup %d in switcher %s\n", u8, pSwitcher->pszDesc)); @@ -721,7 +864,7 @@ static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR } } -#ifdef LOG_ENABLED +# ifdef LOG_ENABLED /* * If Log2 is enabled disassemble the switcher code. * @@ -856,9 +999,25 @@ static void vmmR3SwitcherGenericRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR } } } -#endif +# endif } +/** + * Wrapper around SELMGetHyperGDT() that avoids calling it when raw-mode context + * is not initialized. + * + * @returns Raw-mode contet GDT address. Null pointer if not applicable. + * @param pVM The cross context VM structure. + */ +static RTRCPTR vmmR3SwitcherGetHyperGDT(PVM pVM) +{ + if (HMIsRawModeCtxNeeded(pVM)) + return SELMGetHyperGDT(pVM); +# if HC_ARCH_BITS != 32 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) + AssertFailed(); /* This path is only applicable to some 32-bit hosts. */ +# endif + return NIL_RTRCPTR; +} /** * Relocator for the 32-Bit to 32-Bit world switcher. @@ -886,7 +1045,7 @@ DECLCALLBACK(void) vmmR3Switcher32BitToPAE_Relocate(PVM pVM, PVMMSWITCHERDEF pSw DECLCALLBACK(void) vmmR3Switcher32BitToAMD64_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode) { vmmR3SwitcherGenericRelocate(pVM, pSwitcher, R0PtrCode, pu8CodeR3, GCPtrCode, u32IDCode, - SELMGetHyperCS(pVM), SELMGetHyperDS(pVM), SELMGetHyperTSS(pVM), SELMGetHyperGDT(pVM), SELMGetHyperCS64(pVM)); + SELMGetHyperCS(pVM), SELMGetHyperDS(pVM), SELMGetHyperTSS(pVM), vmmR3SwitcherGetHyperGDT(pVM), SELMGetHyperCS64(pVM)); } @@ -915,7 +1074,7 @@ DECLCALLBACK(void) vmmR3SwitcherPAEToPAE_Relocate(PVM pVM, PVMMSWITCHERDEF pSwit DECLCALLBACK(void) vmmR3SwitcherPAEToAMD64_Relocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, RTR0PTR R0PtrCode, uint8_t *pu8CodeR3, RTGCPTR GCPtrCode, uint32_t u32IDCode) { vmmR3SwitcherGenericRelocate(pVM, pSwitcher, R0PtrCode, pu8CodeR3, GCPtrCode, u32IDCode, - SELMGetHyperCS(pVM), SELMGetHyperDS(pVM), SELMGetHyperTSS(pVM), SELMGetHyperGDT(pVM), SELMGetHyperCS64(pVM)); + SELMGetHyperCS(pVM), SELMGetHyperDS(pVM), SELMGetHyperTSS(pVM), vmmR3SwitcherGetHyperGDT(pVM), SELMGetHyperCS64(pVM)); } @@ -959,14 +1118,17 @@ VMMR3_INT_DECL(int) VMMR3SelectSwitcher(PVM pVM, VMMSWITCHER enmSwitcher) return VERR_INVALID_PARAMETER; } - /* Do nothing if the switcher is disabled. */ - if (pVM->vmm.s.fSwitcherDisabled) - return VINF_SUCCESS; + /* + * Override it if HM is active. + */ + if (HMIsEnabled(pVM)) + pVM->vmm.s.enmSwitcher = HC_ARCH_BITS == 64 ? VMMSWITCHER_AMD64_STUB : VMMSWITCHER_X86_STUB; /* * Select the new switcher. */ - PVMMSWITCHERDEF pSwitcher = s_apSwitchers[enmSwitcher]; + const PVMMSWITCHERDEF *papSwitchers = HMIsEnabled(pVM) ? g_apHmSwitchers : g_apRawModeSwitchers; + PVMMSWITCHERDEF pSwitcher = papSwitchers[enmSwitcher]; if (pSwitcher) { Log(("VMMR3SelectSwitcher: enmSwitcher %d -> %d %s\n", pVM->vmm.s.enmSwitcher, enmSwitcher, pSwitcher->pszDesc)); @@ -986,25 +1148,7 @@ VMMR3_INT_DECL(int) VMMR3SelectSwitcher(PVM pVM, VMMSWITCHER enmSwitcher) return VERR_NOT_IMPLEMENTED; } - -/** - * Disable the switcher logic permanently. - * - * @returns VBox status code. - * @param pVM Pointer to the VM. - */ -VMMR3_INT_DECL(int) VMMR3DisableSwitcher(PVM pVM) -{ -/** @todo r=bird: I would suggest that we create a dummy switcher which just does something like: - * @code - * mov eax, VERR_VMM_DUMMY_SWITCHER - * ret - * @endcode - * And then check for fSwitcherDisabled in VMMR3SelectSwitcher() in order to prevent it from being removed. - */ - pVM->vmm.s.fSwitcherDisabled = true; - return VINF_SUCCESS; -} +#endif /* #defined(VBOX_WITH_RAW_MODE) || (HC_ARCH_BITS != 64 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)) */ /** @@ -1019,20 +1163,21 @@ VMMR3_INT_DECL(RTR0PTR) VMMR3GetHostToGuestSwitcher(PVM pVM, VMMSWITCHER enmSwit /* * Validate input. */ - if ( enmSwitcher < VMMSWITCHER_INVALID - || enmSwitcher >= VMMSWITCHER_MAX) - { - AssertMsgFailed(("Invalid input enmSwitcher=%d\n", enmSwitcher)); - return NIL_RTR0PTR; - } + AssertMsgReturn( enmSwitcher == VMMSWITCHER_32_TO_AMD64 + || enmSwitcher == VMMSWITCHER_PAE_TO_AMD64, + ("%d\n", enmSwitcher), + NIL_RTR0PTR); + AssertReturn(HMIsEnabled(pVM), NIL_RTR0PTR); /* * Select the new switcher. */ - PVMMSWITCHERDEF pSwitcher = s_apSwitchers[enmSwitcher]; + const PVMMSWITCHERDEF *papSwitchers = g_apHmSwitchers; + PVMMSWITCHERDEF pSwitcher = papSwitchers[enmSwitcher]; if (pSwitcher) { - RTR0PTR pbCodeR0 = (RTR0PTR)pVM->vmm.s.pvCoreCodeR0 + pVM->vmm.s.aoffSwitchers[enmSwitcher]; /** @todo fix the pvCoreCodeR0 type */ + /** @todo fix the pvCoreCodeR0 type */ + RTR0PTR pbCodeR0 = (RTR0PTR)pVM->vmm.s.pvCoreCodeR0 + pVM->vmm.s.aoffSwitchers[enmSwitcher]; return pbCodeR0 + pSwitcher->offR0ToRawMode; } return NIL_RTR0PTR; |
