diff options
Diffstat (limited to 'src/VBox/VMM/VMMAll/SELMAll.cpp')
| -rw-r--r-- | src/VBox/VMM/VMMAll/SELMAll.cpp | 106 |
1 files changed, 58 insertions, 48 deletions
diff --git a/src/VBox/VMM/VMMAll/SELMAll.cpp b/src/VBox/VMM/VMMAll/SELMAll.cpp index 0b9a9c6d..317727dc 100644 --- a/src/VBox/VMM/VMMAll/SELMAll.cpp +++ b/src/VBox/VMM/VMMAll/SELMAll.cpp @@ -22,9 +22,11 @@ #define LOG_GROUP LOG_GROUP_SELM #include <VBox/vmm/selm.h> #include <VBox/vmm/stam.h> +#include <VBox/vmm/em.h> #include <VBox/vmm/mm.h> +#include <VBox/vmm/hm.h> #include <VBox/vmm/pgm.h> -#include <VBox/vmm/hwaccm.h> +#include <VBox/vmm/hm.h> #include "SELMInternal.h" #include <VBox/vmm/vm.h> #include <VBox/err.h> @@ -33,6 +35,8 @@ #include <VBox/vmm/vmm.h> #include <iprt/x86.h> +#include "SELMInline.h" + /******************************************************************************* * Global Variables * @@ -60,6 +64,7 @@ static char const g_aszSRegNms[X86_SREG_COUNT][4] = { "ES", "CS", "SS", "DS", "F VMMDECL(RTGCPTR) SELMToFlatBySel(PVM pVM, RTSEL Sel, RTGCPTR Addr) { Assert(pVM->cCpus == 1 && !CPUMIsGuestInLongMode(VMMGetCpu(pVM))); /* DON'T USE! */ + Assert(!HMIsEnabled(pVM)); /** @todo check the limit. */ X86DESC Desc; @@ -183,7 +188,6 @@ VMMDECL(int) SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, return VINF_SUCCESS; } - #ifdef VBOX_WITH_RAW_MODE_NOT_R0 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg)) CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg); @@ -318,6 +322,7 @@ VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPT uint32_t fFlags, PRTGCPTR ppvGC, uint32_t *pcb) { Assert(!CPUMIsGuestInLongMode(pVCpu)); /* DON'T USE! (Accessing shadow GDT/LDT.) */ + Assert(!HMIsEnabled(pVCpu->CTX_SUFF(pVM))); /* * Deal with real & v86 mode first. @@ -484,6 +489,8 @@ VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPT static void selLoadHiddenSelectorRegFromGuestTable(PVMCPU pVCpu, PCCPUMCTX pCtx, PCPUMSELREG pSReg, RTGCPTR GCPtrDesc, RTSEL const Sel, uint32_t const iSReg) { + Assert(!HMIsEnabled(pVCpu->CTX_SUFF(pVM))); + /* * Try read the entry. */ @@ -537,6 +544,7 @@ VMM_INT_DECL(void) SELMLoadHiddenSelectorReg(PVMCPU pVCpu, PCCPUMCTX pCtx, PCPUM PVM pVM = pVCpu->CTX_SUFF(pVM); Assert(pVM->cCpus == 1); + Assert(!HMIsEnabled(pVM)); /* @@ -630,6 +638,8 @@ DECLINLINE(int) selmValidateAndConvertCSAddrRawMode(PVM pVM, PVMCPU pVCpu, RTSEL PRTGCPTR ppvFlat, uint32_t *pcBits) { NOREF(pVCpu); + Assert(!HMIsEnabled(pVM)); + /** @todo validate limit! */ X86DESC Desc; if (!(SelCS & X86_SEL_LDT)) @@ -714,40 +724,27 @@ DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, R if ( pSRegCS->Attr.n.u1DescType == 1 && (pSRegCS->Attr.n.u4Type & X86_SEL_TYPE_CODE)) { + /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0 + (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */ + if ( pSRegCS->Attr.n.u1Long + && CPUMIsGuestInLongMode(pVCpu)) + { + *ppvFlat = Addr; + return VINF_SUCCESS; + } + /* - * Check level. + * Limit check. Note that the limit in the hidden register is the + * final value. The granularity bit was included in its calculation. */ - unsigned uLevel = RT_MAX(SelCPL & X86_SEL_RPL, SelCS & X86_SEL_RPL); - if ( !(pSRegCS->Attr.n.u4Type & X86_SEL_TYPE_CONF) - ? uLevel <= pSRegCS->Attr.n.u2Dpl - : uLevel >= pSRegCS->Attr.n.u2Dpl /* hope I got this right now... */ - ) + uint32_t u32Limit = pSRegCS->u32Limit; + if ((RTGCUINTPTR)Addr <= u32Limit) { - /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0 - (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */ - if ( pSRegCS->Attr.n.u1Long - && CPUMIsGuestInLongMode(pVCpu)) - { - *ppvFlat = Addr; - return VINF_SUCCESS; - } - - /* - * Limit check. Note that the limit in the hidden register is the - * final value. The granularity bit was included in its calculation. - */ - uint32_t u32Limit = pSRegCS->u32Limit; - if ((RTGCUINTPTR)Addr <= u32Limit) - { - *ppvFlat = Addr + pSRegCS->u64Base; - return VINF_SUCCESS; - } - - return VERR_OUT_OF_SELECTOR_BOUNDS; + *ppvFlat = Addr + pSRegCS->u64Base; + return VINF_SUCCESS; } - Log(("selmValidateAndConvertCSAddrHidden: Invalid RPL Attr.n.u4Type=%x cpl=%x dpl=%x\n", - pSRegCS->Attr.n.u4Type, uLevel, pSRegCS->Attr.n.u2Dpl)); - return VERR_INVALID_RPL; + + return VERR_OUT_OF_SELECTOR_BOUNDS; } return VERR_NOT_CODE_SELECTOR; } @@ -785,10 +782,10 @@ VMMDECL(int) SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS Efl, RTSEL Sel CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSRegCS); /* Undo ring compression. */ - if ((SelCPL & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM))) + if ((SelCPL & X86_SEL_RPL) == 1 && !HMIsEnabled(pVCpu->CTX_SUFF(pVM))) SelCPL &= ~X86_SEL_RPL; Assert(pSRegCS->Sel == SelCS); - if ((SelCS & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM))) + if ((SelCS & X86_SEL_RPL) == 1 && !HMIsEnabled(pVCpu->CTX_SUFF(pVM))) SelCS &= ~X86_SEL_RPL; #else Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSRegCS)); @@ -832,12 +829,31 @@ VMMDECL(void) SELMSetTrap8EIP(PVM pVM, uint32_t u32EIP) */ void selmSetRing1Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp) { + Assert(!HMIsEnabled(pVM)); Assert((ss & 1) || esp == 0); pVM->selm.s.Tss.ss1 = ss; pVM->selm.s.Tss.esp1 = (uint32_t)esp; } +#ifdef VBOX_WITH_RAW_RING1 +/** + * Sets ss:esp for ring1 in main Hypervisor's TSS. + * + * @param pVM Pointer to the VM. + * @param ss Ring2 SS register value. Pass 0 if invalid. + * @param esp Ring2 ESP register value. + */ +void selmSetRing2Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp) +{ + Assert(!HMIsEnabled(pVM)); + Assert((ss & 3) == 2 || esp == 0); + pVM->selm.s.Tss.ss2 = ss; + pVM->selm.s.Tss.esp2 = (uint32_t)esp; +} +#endif + + #ifdef VBOX_WITH_RAW_MODE_NOT_R0 /** * Gets ss:esp for ring1 in main Hypervisor's TSS. @@ -851,11 +867,14 @@ void selmSetRing1Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp) */ VMMDECL(int) SELMGetRing1Stack(PVM pVM, uint32_t *pSS, PRTGCPTR32 pEsp) { + Assert(!HMIsEnabled(pVM)); Assert(pVM->cCpus == 1); PVMCPU pVCpu = &pVM->aCpus[0]; +#ifdef SELM_TRACK_GUEST_TSS_CHANGES if (pVM->selm.s.fSyncTSSRing0Stack) { +#endif RTGCPTR GCPtrTss = pVM->selm.s.GCPtrGuestTss; int rc; VBOXTSS tss; @@ -912,7 +931,9 @@ l_tryagain: /* Update our TSS structure for the guest's ring 1 stack */ selmSetRing1Stack(pVM, tss.ss0 | 1, (RTGCPTR32)tss.esp0); pVM->selm.s.fSyncTSSRing0Stack = false; +#ifdef SELM_TRACK_GUEST_TSS_CHANGES } +#endif *pSS = pVM->selm.s.Tss.ss1; *pEsp = (RTGCPTR32)pVM->selm.s.Tss.esp1; @@ -922,18 +943,7 @@ l_tryagain: #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */ -/** - * Returns Guest TSS pointer - * - * @returns Pointer to the guest TSS, RTRCPTR_MAX if not being monitored. - * @param pVM Pointer to the VM. - */ -VMMDECL(RTGCPTR) SELMGetGuestTSS(PVM pVM) -{ - return (RTGCPTR)pVM->selm.s.GCPtrGuestTss; -} - -#ifdef VBOX_WITH_RAW_MODE_NOT_R0 +#if defined(VBOX_WITH_RAW_MODE) || (HC_ARCH_BITS != 64 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)) /** * Gets the hypervisor code selector (CS). @@ -1007,7 +1017,7 @@ VMMDECL(RTRCPTR) SELMGetHyperGDT(PVM pVM) return (RTRCPTR)MMHyperR3ToRC(pVM, pVM->selm.s.paGdtR3); } -#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */ +#endif /* defined(VBOX_WITH_RAW_MODE) || (HC_ARCH_BITS != 64 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)) */ /** * Gets info about the current TSS. @@ -1054,7 +1064,7 @@ VMMDECL(int) SELMGetTSSInfo(PVM pVM, PVMCPU pVCpu, PRTGCUINTPTR pGCPtrTss, PRTGC */ VMMDECL(void) SELMShadowCR3Changed(PVM pVM, PVMCPU pVCpu) { - /** @todo SMP support!! */ + /** @todo SMP support!! (64-bit guest scenario, primarily) */ pVM->selm.s.Tss.cr3 = PGMGetHyperCR3(pVCpu); pVM->selm.s.TssTrap08.cr3 = PGMGetInterRCCR3(pVM, pVCpu); } |
