Changeset 42186 in vbox for trunk/src/VBox
- Timestamp:
- Jul 17, 2012 1:32:15 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 79186
- Location:
- trunk/src/VBox
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Disassembler/DisasmReg.cpp
r41906 r42186 415 415 * 416 416 */ 417 DISDECL(int) DISFetchRegSegEx(PCCPUMCTXCORE pCtx, DISSELREG sel, RTSEL *pVal, CPUMSELREGHID **ppSelHidReg) 418 { 419 AssertReturn((unsigned)sel < RT_ELEMENTS(g_aRegSegIndex), VERR_INVALID_PARAMETER); 420 421 AssertCompile(sizeof(uint16_t) == sizeof(RTSEL)); 422 *pVal = DIS_READ_REGSEG(pCtx, sel); 423 *ppSelHidReg = (CPUMSELREGHID *)((char *)pCtx + g_aRegHidSegIndex[sel]); 417 DISDECL(int) DISFetchRegSegEx(PCPUMCTXCORE pCtx, DISSELREG sel, PCPUMSELREG *ppSelReg) 418 { 419 AssertReturnStmt((unsigned)sel < RT_ELEMENTS(g_aRegSegIndex), *ppSelReg = NULL, VERR_INVALID_PARAMETER); 420 *ppSelReg = (CPUMSELREG *)((uintptr_t)pCtx + g_aRegHidSegIndex[sel]); 424 421 return VINF_SUCCESS; 425 422 } -
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r42166 r42186 2602 2602 return enmMode; 2603 2603 } 2604 2605 2606 /** 2607 * Figure whether the CPU is currently executing 16, 32 or 64 bit code. 2608 * 2609 * @returns 16, 32 or 64. 2610 * @param pVCpu The current virtual CPU. 2611 */ 2612 VMMDECL(uint32_t) CPUMGetGuestCodeBits(PVMCPU pVCpu) 2613 { 2614 if (!(pVCpu->cpum.s.Guest.cr0 & X86_CR0_PE)) 2615 return 16; 2616 2617 if (pVCpu->cpum.s.Guest.eflags.Bits.u1VM) 2618 { 2619 Assert(!(pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA)); 2620 return 16; 2621 } 2622 2623 CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true); 2624 if ( pVCpu->cpum.s.Guest.cs.Attr.n.u1Long 2625 && (pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA)) 2626 return 64; 2627 2628 if (pVCpu->cpum.s.Guest.cs.Attr.n.u1DefBig) 2629 return 32; 2630 2631 return 16; 2632 } 2633 2634 2635 VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu) 2636 { 2637 if (!(pVCpu->cpum.s.Guest.cr0 & X86_CR0_PE)) 2638 return DISCPUMODE_16BIT; 2639 2640 if (pVCpu->cpum.s.Guest.eflags.Bits.u1VM) 2641 { 2642 Assert(!(pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA)); 2643 return DISCPUMODE_16BIT; 2644 } 2645 2646 CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true); 2647 if ( pVCpu->cpum.s.Guest.cs.Attr.n.u1Long 2648 && (pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA)) 2649 return DISCPUMODE_64BIT; 2650 2651 if (pVCpu->cpum.s.Guest.cs.Attr.n.u1DefBig) 2652 return DISCPUMODE_32BIT; 2653 2654 return DISCPUMODE_16BIT; 2655 } 2656 -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r42165 r42186 365 365 366 366 /** 367 * Disassembles oneinstruction.367 * Disassembles the current instruction. 368 368 * 369 369 * @returns VBox status code, see SELMToFlatEx and EMInterpretDisasOneEx for … … 373 373 * @param pVM Pointer to the VM. 374 374 * @param pVCpu Pointer to the VMCPU. 375 * @param pCtxCore The context core (used for both the mode and instruction).376 375 * @param pDis Where to return the parsed instruction info. 377 376 * @param pcbInstr Where to return the instruction size. (optional) 378 377 */ 379 VMMDECL(int) EMInterpretDisasOne(PVM pVM, PVMCPU pVCpu, PCCPUMCTXCORE pCtxCore, PDISCPUSTATE pDis, unsigned *pcbInstr) 380 { 378 VMMDECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, unsigned *pcbInstr) 379 { 380 PCPUMCTXCORE pCtxCore = CPUMCTX2CORE(CPUMQueryGuestCtxPtr(pVCpu)); 381 381 RTGCPTR GCPtrInstr; 382 382 #if 0 … … 384 384 #else 385 385 /** @todo Get the CPU mode as well while we're at it! */ 386 int rc = SELMValidateAndConvertCSAddr(pVCpu, pCtxCore->eflags, pCtxCore->ss.Sel, pCtxCore->cs.Sel, 387 &pCtxCore->cs,pCtxCore->rip, &GCPtrInstr);386 int rc = SELMValidateAndConvertCSAddr(pVCpu, pCtxCore->eflags, pCtxCore->ss.Sel, pCtxCore->cs.Sel, &pCtxCore->cs, 387 pCtxCore->rip, &GCPtrInstr); 388 388 #endif 389 389 if (RT_FAILURE(rc)) … … 415 415 PDISCPUSTATE pDis, unsigned *pcbInstr) 416 416 { 417 DISCPUMODE enmCpuMode = SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs.Sel, (PCPUMSELREGHID)&pCtxCore->cs); 417 Assert(pCtxCore == CPUMGetGuestCtxCore(pVCpu)); 418 DISCPUMODE enmCpuMode = CPUMGetGuestDisMode(pVCpu); 418 419 /** @todo Deal with too long instruction (=> \#GP), opcode read errors (=> 419 420 * \#PF, \#GP, \#??), undefined opcodes (=> \#UD), and such. */ … … 462 463 uint32_t cbOp; 463 464 PDISCPUSTATE pDis = &pVCpu->em.s.DisState; 464 pDis->uCpuMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs);465 pDis->uCpuMode = CPUMGetGuestDisMode(pVCpu); 465 466 rc = emDisCoreOne(pVCpu->CTX_SUFF(pVM), pVCpu, pDis, (RTGCUINTPTR)pbCode, &cbOp); 466 467 if (RT_SUCCESS(rc)) … … 517 518 uint32_t cbOp; 518 519 PDISCPUSTATE pDis = &pVCpu->em.s.DisState; 519 pDis->uCpuMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs);520 pDis->uCpuMode = CPUMGetGuestDisMode(pVCpu); 520 521 rc = emDisCoreOne(pVCpu->CTX_SUFF(pVM), pVCpu, pDis, (RTGCUINTPTR)pbCode, &cbOp); 521 522 if (RT_SUCCESS(rc)) … … 1547 1548 1548 1549 /* Read stack value first */ 1549 if ( SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, &pRegFrame->ss) == DISCPUMODE_16BIT)1550 if (CPUMGetGuestCodeBits(pVCpu) == 16) 1550 1551 return VERR_EM_INTERPRETER; /* No legacy 16 bits stuff here, please. */ 1551 1552 -
trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
r42165 r42186 1521 1521 PDISCPUSTATE pDis = &pVCpu->iom.s.DisState; 1522 1522 unsigned cbOp; 1523 rc = EMInterpretDisas One(pVM, pVCpu, pCtxCore, pDis, &cbOp);1523 rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp); 1524 1524 if (RT_FAILURE(rc)) 1525 1525 { -
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r41939 r42186 908 908 PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState; 909 909 uint32_t cbOp; 910 rc = EMInterpretDisas One(pVM, pVCpu, pRegFrame, pDis, &cbOp);910 rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp); 911 911 912 912 /* For now we'll restrict this to rep movsw/d instructions */ -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r41965 r42186 105 105 uint32_t cbOp; 106 106 PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState; 107 rc = EMInterpretDisas One(pVM, pVCpu, pRegFrame, pDis, &cbOp);107 rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp); 108 108 if ( RT_SUCCESS(rc) 109 109 && pDis->uCpuMode == DISCPUMODE_32BIT /** @todo why does this matter? */ -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r42185 r42186 1089 1089 */ 1090 1090 PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState; 1091 int rc = EMInterpretDisas One(pVM, pVCpu, pRegFrame, pDis, NULL);1091 int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL); 1092 1092 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 1093 1093 { -
trunk/src/VBox/VMM/VMMAll/SELMAll.cpp
r42165 r42186 5 5 6 6 /* 7 * Copyright (C) 2006-20 07Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 25 25 #include <VBox/vmm/mm.h> 26 26 #include <VBox/vmm/pgm.h> 27 #include <VBox/vmm/hwaccm.h> 27 28 #include "SELMInternal.h" 28 29 #include <VBox/vmm/vm.h> … … 36 37 37 38 38 #ifndef IN_RING0 39 39 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 40 40 /** 41 41 * Converts a GC selector based address to a flat address. … … 67 67 return (RTGCPTR)(((RTGCUINTPTR)Addr + X86DESC_BASE(Desc)) & 0xffffffff); 68 68 } 69 #endif /* !IN_RING0 */69 #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */ 70 70 71 71 … … 84 84 VMMDECL(RTGCPTR) SELMToFlat(PVM pVM, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr) 85 85 { 86 PCPUMSELREGHID pHiddenSel; 87 RTSEL Sel; 88 int rc; 86 PCPUMSELREG pSReg; 89 87 PVMCPU pVCpu = VMMGetCpu(pVM); 90 88 91 rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel); AssertRC(rc);89 int rc = DISFetchRegSegEx(pCtxCore, SelReg, &pSReg); AssertRC(rc); 92 90 93 91 /* … … 99 97 RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff; 100 98 if (CPUMAreHiddenSelRegsValid(pVCpu)) 101 uFlat += p HiddenSel->u64Base;99 uFlat += pSReg->u64Base; 102 100 else 103 uFlat += ((RTGCUINTPTR) Sel << 4);101 uFlat += ((RTGCUINTPTR)pSReg->Sel << 4); 104 102 return (RTGCPTR)uFlat; 105 103 } 106 104 107 #ifdef IN_RING0 108 Assert(CPUMAreHiddenSelRegsValid(pVCpu)); 105 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 106 /** @todo when we're in 16 bits mode, we should cut off the address as well?? */ 107 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg)) 108 CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg); 109 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs)) 110 CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, &pCtxCore->cs); 109 111 #else 110 /** @todo when we're in 16 bits mode, we should cut off the address as well.. */ 111 if (!CPUMAreHiddenSelRegsValid(pVCpu)) 112 return SELMToFlatBySel(pVM, Sel, Addr); 112 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg)); 113 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs)); 113 114 #endif 114 115 115 /* 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). */ 116 /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0 117 (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */ 116 118 if ( pCtxCore->cs.Attr.n.u1Long 117 119 && CPUMIsGuestInLongMode(pVCpu)) … … 121 123 case DISSELREG_FS: 122 124 case DISSELREG_GS: 123 return (RTGCPTR)(p HiddenSel->u64Base + Addr);125 return (RTGCPTR)(pSReg->u64Base + Addr); 124 126 125 127 default: … … 129 131 130 132 /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */ 131 Assert(p HiddenSel->u64Base <= 0xffffffff);132 return ((p HiddenSel->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff);133 Assert(pSReg->u64Base <= 0xffffffff); 134 return ((pSReg->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff); 133 135 } 134 136 … … 148 150 * @param ppvGC Where to store the GC flat address. 149 151 */ 150 VMMDECL(int) SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PC CPUMCTXCORE pCtxCore, RTGCPTR Addr, unsignedfFlags, PRTGCPTR ppvGC)152 VMMDECL(int) SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr, uint32_t fFlags, PRTGCPTR ppvGC) 151 153 { 152 154 /* 153 155 * Fetch the selector first. 154 156 */ 155 PCPUMSELREGHID pHiddenSel; 156 RTSEL Sel; 157 158 int rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel); 159 AssertRC(rc); 157 PCPUMSELREG pSReg; 158 int rc = DISFetchRegSegEx(pCtxCore, SelReg, &pSReg); 159 AssertRCReturn(rc, rc); AssertPtr(pSReg); 160 160 161 161 /* … … 168 168 if (ppvGC) 169 169 { 170 if ( pHiddenSel 171 && CPUMAreHiddenSelRegsValid(pVCpu)) 172 *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat); 170 if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg)) 171 *ppvGC = pSReg->u64Base + uFlat; 173 172 else 174 *ppvGC = ( RTGCPTR)(((RTGCUINTPTR)Sel << 4) + uFlat);173 *ppvGC = ((RTGCUINTPTR)pSReg->Sel << 4) + uFlat; 175 174 } 176 175 return VINF_SUCCESS; … … 178 177 179 178 180 uint32_t u32Limit; 181 RTGCPTR pvFlat; 182 uint32_t u1Present, u1DescType, u1Granularity, u4Type; 183 184 /** @todo when we're in 16 bits mode, we should cut off the address as well.. */ 185 #ifndef IN_RC 186 if ( pHiddenSel 187 && CPUMAreHiddenSelRegsValid(pVCpu)) 188 { 189 bool fCheckLimit = true; 190 191 u1Present = pHiddenSel->Attr.n.u1Present; 192 u1Granularity = pHiddenSel->Attr.n.u1Granularity; 193 u1DescType = pHiddenSel->Attr.n.u1DescType; 194 u4Type = pHiddenSel->Attr.n.u4Type; 195 u32Limit = pHiddenSel->u32Limit; 196 197 /* 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). */ 198 if ( pCtxCore->cs.Attr.n.u1Long 199 && CPUMIsGuestInLongMode(pVCpu)) 200 { 201 fCheckLimit = false; 202 switch (SelReg) 203 { 204 case DISSELREG_FS: 205 case DISSELREG_GS: 206 pvFlat = (pHiddenSel->u64Base + Addr); 207 break; 208 209 default: 210 pvFlat = Addr; 211 break; 212 } 213 } 214 else 215 { 216 /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */ 217 Assert(pHiddenSel->u64Base <= 0xffffffff); 218 pvFlat = (RTGCPTR)((pHiddenSel->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff); 219 } 220 221 /* 222 * Check if present. 223 */ 224 if (u1Present) 225 { 226 /* 227 * Type check. 228 */ 229 switch (u4Type) 230 { 231 232 /** Read only selector type. */ 233 case X86_SEL_TYPE_RO: 234 case X86_SEL_TYPE_RO_ACC: 235 case X86_SEL_TYPE_RW: 236 case X86_SEL_TYPE_RW_ACC: 237 case X86_SEL_TYPE_EO: 238 case X86_SEL_TYPE_EO_ACC: 239 case X86_SEL_TYPE_ER: 240 case X86_SEL_TYPE_ER_ACC: 241 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 242 { 243 /** @todo fix this mess */ 244 } 245 /* check limit. */ 246 if (fCheckLimit && (RTGCUINTPTR)Addr > u32Limit) 179 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 180 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg)) 181 CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg); 182 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs)) 183 CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, &pCtxCore->cs); 184 #else 185 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg)); 186 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs)); 187 #endif 188 189 /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0 190 (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */ 191 RTGCPTR pvFlat; 192 bool fCheckLimit = true; 193 if ( pCtxCore->cs.Attr.n.u1Long 194 && CPUMIsGuestInLongMode(pVCpu)) 195 { 196 fCheckLimit = false; 197 switch (SelReg) 198 { 199 case DISSELREG_FS: 200 case DISSELREG_GS: 201 pvFlat = pSReg->u64Base + Addr; 202 break; 203 204 default: 205 pvFlat = Addr; 206 break; 207 } 208 } 209 else 210 { 211 /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */ 212 Assert(pSReg->u64Base <= UINT32_C(0xffffffff)); 213 pvFlat = pSReg->u64Base + Addr; 214 pvFlat &= UINT32_C(0xffffffff); 215 } 216 217 /* 218 * Check type if present. 219 */ 220 if (pSReg->Attr.n.u1Present) 221 { 222 switch (pSReg->Attr.n.u4Type) 223 { 224 /* Read only selector type. */ 225 case X86_SEL_TYPE_RO: 226 case X86_SEL_TYPE_RO_ACC: 227 case X86_SEL_TYPE_RW: 228 case X86_SEL_TYPE_RW_ACC: 229 case X86_SEL_TYPE_EO: 230 case X86_SEL_TYPE_EO_ACC: 231 case X86_SEL_TYPE_ER: 232 case X86_SEL_TYPE_ER_ACC: 233 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 234 { 235 /** @todo fix this mess */ 236 } 237 /* check limit. */ 238 if (fCheckLimit && Addr > pSReg->u32Limit) 239 return VERR_OUT_OF_SELECTOR_BOUNDS; 240 /* ok */ 241 if (ppvGC) 242 *ppvGC = pvFlat; 243 return VINF_SUCCESS; 244 245 case X86_SEL_TYPE_EO_CONF: 246 case X86_SEL_TYPE_EO_CONF_ACC: 247 case X86_SEL_TYPE_ER_CONF: 248 case X86_SEL_TYPE_ER_CONF_ACC: 249 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 250 { 251 /** @todo fix this mess */ 252 } 253 /* check limit. */ 254 if (fCheckLimit && Addr > pSReg->u32Limit) 255 return VERR_OUT_OF_SELECTOR_BOUNDS; 256 /* ok */ 257 if (ppvGC) 258 *ppvGC = pvFlat; 259 return VINF_SUCCESS; 260 261 case X86_SEL_TYPE_RO_DOWN: 262 case X86_SEL_TYPE_RO_DOWN_ACC: 263 case X86_SEL_TYPE_RW_DOWN: 264 case X86_SEL_TYPE_RW_DOWN_ACC: 265 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 266 { 267 /** @todo fix this mess */ 268 } 269 /* check limit. */ 270 if (fCheckLimit) 271 { 272 if (!pSReg->Attr.n.u1Granularity && Addr > UINT32_C(0xffff)) 247 273 return VERR_OUT_OF_SELECTOR_BOUNDS; 248 /* ok */ 249 if (ppvGC) 250 *ppvGC = pvFlat; 251 return VINF_SUCCESS; 252 253 case X86_SEL_TYPE_EO_CONF: 254 case X86_SEL_TYPE_EO_CONF_ACC: 255 case X86_SEL_TYPE_ER_CONF: 256 case X86_SEL_TYPE_ER_CONF_ACC: 257 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 258 { 259 /** @todo fix this mess */ 260 } 261 /* check limit. */ 262 if (fCheckLimit && (RTGCUINTPTR)Addr > u32Limit) 274 if (Addr <= pSReg->u32Limit) 263 275 return VERR_OUT_OF_SELECTOR_BOUNDS; 264 /* ok */ 265 if (ppvGC) 266 *ppvGC = pvFlat; 267 return VINF_SUCCESS; 268 269 case X86_SEL_TYPE_RO_DOWN: 270 case X86_SEL_TYPE_RO_DOWN_ACC: 271 case X86_SEL_TYPE_RW_DOWN: 272 case X86_SEL_TYPE_RW_DOWN_ACC: 273 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 274 { 275 /** @todo fix this mess */ 276 } 277 /* check limit. */ 278 if (fCheckLimit) 279 { 280 if (!u1Granularity && (RTGCUINTPTR)Addr > (RTGCUINTPTR)0xffff) 281 return VERR_OUT_OF_SELECTOR_BOUNDS; 282 if ((RTGCUINTPTR)Addr <= u32Limit) 283 return VERR_OUT_OF_SELECTOR_BOUNDS; 284 } 285 /* ok */ 286 if (ppvGC) 287 *ppvGC = pvFlat; 288 return VINF_SUCCESS; 289 290 default: 291 return VERR_INVALID_SELECTOR; 292 293 } 294 } 295 } 296 # ifndef IN_RING0 297 else 298 # endif 299 #endif /* !IN_RC */ 300 #ifndef IN_RING0 301 { 302 X86DESC Desc; 303 304 PVM pVM = pVCpu->CTX_SUFF(pVM); 305 if (!(Sel & X86_SEL_LDT)) 306 { 307 if ( !(fFlags & SELMTOFLAT_FLAGS_HYPER) 308 && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt) 276 } 277 /* ok */ 278 if (ppvGC) 279 *ppvGC = pvFlat; 280 return VINF_SUCCESS; 281 282 default: 309 283 return VERR_INVALID_SELECTOR; 310 Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT]; 311 } 312 else 313 { 314 if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit) 315 return VERR_INVALID_SELECTOR; 316 317 /** @todo handle LDT page(s) not present! */ 318 PX86DESC paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper); 319 Desc = paLDT[Sel >> X86_SEL_SHIFT]; 320 } 321 322 /* calc limit. */ 323 u32Limit = X86DESC_LIMIT(Desc); 324 if (Desc.Gen.u1Granularity) 325 u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK; 326 327 /* calc address assuming straight stuff. */ 328 pvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc)); 329 330 /* Cut the address to 32 bits. */ 331 Assert(!CPUMIsGuestInLongMode(pVCpu)); 332 pvFlat &= 0xffffffff; 333 334 u1Present = Desc.Gen.u1Present; 335 u1Granularity = Desc.Gen.u1Granularity; 336 u1DescType = Desc.Gen.u1DescType; 337 u4Type = Desc.Gen.u4Type; 338 339 /* 340 * Check if present. 341 */ 342 if (u1Present) 343 { 344 /* 345 * Type check. 346 */ 347 # define BOTH(a, b) ((a << 16) | b) 348 switch (BOTH(u1DescType, u4Type)) 349 { 350 351 /** Read only selector type. */ 352 case BOTH(1,X86_SEL_TYPE_RO): 353 case BOTH(1,X86_SEL_TYPE_RO_ACC): 354 case BOTH(1,X86_SEL_TYPE_RW): 355 case BOTH(1,X86_SEL_TYPE_RW_ACC): 356 case BOTH(1,X86_SEL_TYPE_EO): 357 case BOTH(1,X86_SEL_TYPE_EO_ACC): 358 case BOTH(1,X86_SEL_TYPE_ER): 359 case BOTH(1,X86_SEL_TYPE_ER_ACC): 360 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 361 { 362 /** @todo fix this mess */ 363 } 364 /* check limit. */ 365 if ((RTGCUINTPTR)Addr > u32Limit) 366 return VERR_OUT_OF_SELECTOR_BOUNDS; 367 /* ok */ 368 if (ppvGC) 369 *ppvGC = pvFlat; 370 return VINF_SUCCESS; 371 372 case BOTH(1,X86_SEL_TYPE_EO_CONF): 373 case BOTH(1,X86_SEL_TYPE_EO_CONF_ACC): 374 case BOTH(1,X86_SEL_TYPE_ER_CONF): 375 case BOTH(1,X86_SEL_TYPE_ER_CONF_ACC): 376 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 377 { 378 /** @todo fix this mess */ 379 } 380 /* check limit. */ 381 if ((RTGCUINTPTR)Addr > u32Limit) 382 return VERR_OUT_OF_SELECTOR_BOUNDS; 383 /* ok */ 384 if (ppvGC) 385 *ppvGC = pvFlat; 386 return VINF_SUCCESS; 387 388 case BOTH(1,X86_SEL_TYPE_RO_DOWN): 389 case BOTH(1,X86_SEL_TYPE_RO_DOWN_ACC): 390 case BOTH(1,X86_SEL_TYPE_RW_DOWN): 391 case BOTH(1,X86_SEL_TYPE_RW_DOWN_ACC): 392 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 393 { 394 /** @todo fix this mess */ 395 } 396 /* check limit. */ 397 if (!u1Granularity && (RTGCUINTPTR)Addr > (RTGCUINTPTR)0xffff) 398 return VERR_OUT_OF_SELECTOR_BOUNDS; 399 if ((RTGCUINTPTR)Addr <= u32Limit) 400 return VERR_OUT_OF_SELECTOR_BOUNDS; 401 402 /* ok */ 403 if (ppvGC) 404 *ppvGC = pvFlat; 405 return VINF_SUCCESS; 406 407 case BOTH(0,X86_SEL_TYPE_SYS_286_TSS_AVAIL): 408 case BOTH(0,X86_SEL_TYPE_SYS_LDT): 409 case BOTH(0,X86_SEL_TYPE_SYS_286_TSS_BUSY): 410 case BOTH(0,X86_SEL_TYPE_SYS_286_CALL_GATE): 411 case BOTH(0,X86_SEL_TYPE_SYS_TASK_GATE): 412 case BOTH(0,X86_SEL_TYPE_SYS_286_INT_GATE): 413 case BOTH(0,X86_SEL_TYPE_SYS_286_TRAP_GATE): 414 case BOTH(0,X86_SEL_TYPE_SYS_386_TSS_AVAIL): 415 case BOTH(0,X86_SEL_TYPE_SYS_386_TSS_BUSY): 416 case BOTH(0,X86_SEL_TYPE_SYS_386_CALL_GATE): 417 case BOTH(0,X86_SEL_TYPE_SYS_386_INT_GATE): 418 case BOTH(0,X86_SEL_TYPE_SYS_386_TRAP_GATE): 419 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 420 { 421 /** @todo fix this mess */ 422 } 423 /* check limit. */ 424 if ((RTGCUINTPTR)Addr > u32Limit) 425 return VERR_OUT_OF_SELECTOR_BOUNDS; 426 /* ok */ 427 if (ppvGC) 428 *ppvGC = pvFlat; 429 return VINF_SUCCESS; 430 431 default: 432 return VERR_INVALID_SELECTOR; 433 434 } 435 # undef BOTH 436 } 437 } 438 #endif /* !IN_RING0 */ 284 285 } 286 } 439 287 return VERR_SELECTOR_NOT_PRESENT; 440 288 } 441 289 442 290 443 #if ndef IN_RING0291 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 444 292 /** 445 293 * Converts a GC selector based address to a flat address. … … 452 300 * @param Sel Selector part. 453 301 * @param Addr Address part. 454 * @param pHiddenSel Hidden selector register (can be NULL)455 302 * @param fFlags SELMTOFLAT_FLAGS_* 456 303 * GDT entires are valid. … … 460 307 * @remarks Don't use when in long mode. 461 308 */ 462 VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, PCCPUMSELREGHID pHiddenSel, uint32_t fFlags, PRTGCPTR ppvGC, uint32_t *pcb) 463 { 464 Assert(!CPUMIsGuestInLongMode(pVCpu)); /* DON'T USE! */ 309 VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, 310 uint32_t fFlags, PRTGCPTR ppvGC, uint32_t *pcb) 311 { 312 Assert(!CPUMIsGuestInLongMode(pVCpu)); /* DON'T USE! (Accessing shadow GDT/LDT.) */ 465 313 466 314 /* … … 472 320 RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff; 473 321 if (ppvGC) 474 { 475 if ( pHiddenSel 476 && CPUMAreHiddenSelRegsValid(pVCpu)) 477 *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat); 478 else 479 *ppvGC = (RTGCPTR)(((RTGCUINTPTR)Sel << 4) + uFlat); 480 } 322 *ppvGC = ((RTGCUINTPTR)Sel << 4) + uFlat; 481 323 if (pcb) 482 324 *pcb = 0x10000 - uFlat; … … 484 326 } 485 327 486 487 uint32_t u32Limit; 488 RTGCPTR pvFlat; 489 uint32_t u1Present, u1DescType, u1Granularity, u4Type; 490 491 /** @todo when we're in 16 bits mode, we should cut off the address as well.. */ 492 if ( pHiddenSel 493 && CPUMAreHiddenSelRegsValid(pVCpu)) 494 { 495 u1Present = pHiddenSel->Attr.n.u1Present; 496 u1Granularity = pHiddenSel->Attr.n.u1Granularity; 497 u1DescType = pHiddenSel->Attr.n.u1DescType; 498 u4Type = pHiddenSel->Attr.n.u4Type; 499 500 u32Limit = pHiddenSel->u32Limit; 501 pvFlat = (RTGCPTR)(pHiddenSel->u64Base + (RTGCUINTPTR)Addr); 502 503 if ( !pHiddenSel->Attr.n.u1Long 504 || !CPUMIsGuestInLongMode(pVCpu)) 505 { 506 /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */ 507 pvFlat &= 0xffffffff; 508 } 328 /** @todo when we're in 16 bits mode, we should cut off the address as well?? */ 329 X86DESC Desc; 330 PVM pVM = pVCpu->CTX_SUFF(pVM); 331 if (!(Sel & X86_SEL_LDT)) 332 { 333 if ( !(fFlags & SELMTOFLAT_FLAGS_HYPER) 334 && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt) 335 return VERR_INVALID_SELECTOR; 336 Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT]; 509 337 } 510 338 else 511 339 { 512 X86DESC Desc; 513 514 PVM pVM = pVCpu->CTX_SUFF(pVM); 515 if (!(Sel & X86_SEL_LDT)) 516 { 517 if ( !(fFlags & SELMTOFLAT_FLAGS_HYPER) 518 && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt) 519 return VERR_INVALID_SELECTOR; 520 Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT]; 521 } 522 else 523 { 524 if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit) 525 return VERR_INVALID_SELECTOR; 526 527 /** @todo handle LDT page(s) not present! */ 528 PX86DESC paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper); 529 Desc = paLDT[Sel >> X86_SEL_SHIFT]; 530 } 531 532 /* calc limit. */ 533 u32Limit = X86DESC_LIMIT(Desc); 534 if (Desc.Gen.u1Granularity) 535 u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK; 536 537 /* calc address assuming straight stuff. */ 538 pvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc)); 539 540 /* Cut the address to 32 bits. */ 541 Assert(!CPUMIsGuestInLongMode(pVCpu)); 542 pvFlat &= 0xffffffff; 543 544 u1Present = Desc.Gen.u1Present; 545 u1Granularity = Desc.Gen.u1Granularity; 546 u1DescType = Desc.Gen.u1DescType; 547 u4Type = Desc.Gen.u4Type; 548 } 340 if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit) 341 return VERR_INVALID_SELECTOR; 342 343 /** @todo handle LDT page(s) not present! */ 344 PX86DESC paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper); 345 Desc = paLDT[Sel >> X86_SEL_SHIFT]; 346 } 347 348 /* calc limit. */ 349 uint32_t u32Limit = X86DESC_LIMIT(Desc); 350 if (Desc.Gen.u1Granularity) 351 u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK; 352 353 /* calc address assuming straight stuff. */ 354 RTGCPTR pvFlat = Addr + X86DESC_BASE(Desc); 355 356 /* Cut the address to 32 bits. */ 357 Assert(!CPUMIsGuestInLongMode(pVCpu)); 358 pvFlat &= 0xffffffff; 359 360 uint8_t u1Present = Desc.Gen.u1Present; 361 uint8_t u1Granularity = Desc.Gen.u1Granularity; 362 uint8_t u1DescType = Desc.Gen.u1DescType; 363 uint8_t u4Type = Desc.Gen.u4Type; 549 364 550 365 /* … … 656 471 return VERR_SELECTOR_NOT_PRESENT; 657 472 } 658 #endif /* !IN_RING0 */659 660 661 #ifdef VBOX_WITH_RAW_MODE 473 #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */ 474 475 476 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 662 477 /** 663 478 * CPUM helper that loads the hidden selector register from the descriptor table … … 687 502 RTSEL const Sel = pSReg->Sel; 688 503 504 /** @todo Consider loading these from the shadow tables when possible? */ 689 505 /* 690 506 * Calculate descriptor table entry address. … … 763 579 * @param ppvFlat Where to store the flat address. 764 580 */ 765 DECLINLINE(int) selmValidateAndConvertCSAddrRealMode(PVMCPU pVCpu, RTSEL SelCS, PCCPUMSELREGHID p HidCS, RTGCPTR Addr,581 DECLINLINE(int) selmValidateAndConvertCSAddrRealMode(PVMCPU pVCpu, RTSEL SelCS, PCCPUMSELREGHID pSReg, RTGCPTR Addr, 766 582 PRTGCPTR ppvFlat) 767 583 { 768 RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff;769 if (!p HidCS || !CPUMAreHiddenSelRegsValid(pVCpu))770 uFlat += ( (RTGCUINTPTR)SelCS << 4);584 RTGCUINTPTR uFlat = Addr & 0xffff; 585 if (!pSReg || !CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg)) 586 uFlat += (RTGCUINTPTR)SelCS << 4; 771 587 else 772 uFlat += p HidCS->u64Base;773 *ppvFlat = (RTGCPTR)uFlat;588 uFlat += pSReg->u64Base; 589 *ppvFlat = uFlat; 774 590 return VINF_SUCCESS; 775 591 } 776 592 777 593 778 #if ndef IN_RING0779 /** 780 * Validates and converts a GC selector based code address to a flat 781 * address when in protected/long mode using the standardalgorithm.594 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 595 /** 596 * Validates and converts a GC selector based code address to a flat address 597 * when in protected/long mode using the raw-mode algorithm. 782 598 * 783 599 * @returns VBox status code. 784 * @param pVM Pointer to the VM. 785 * @param pVCpu Pointer to the VMCPU. 786 * @param SelCPL Current privilege level. Get this from SS - CS might be conforming! 787 * A full selector can be passed, we'll only use the RPL part. 788 * @param SelCS Selector part. 789 * @param Addr Address part. 790 * @param ppvFlat Where to store the flat address. 791 * @param pcBits Where to store the segment bitness (16/32/64). Optional. 792 */ 793 DECLINLINE(int) selmValidateAndConvertCSAddrStd(PVM pVM, PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr, 794 PRTGCPTR ppvFlat, uint32_t *pcBits) 600 * @param pVM Pointer to the VM. 601 * @param pVCpu Pointer to the VMCPU. 602 * @param SelCPL Current privilege level. Get this from SS - CS might be 603 * conforming! A full selector can be passed, we'll only 604 * use the RPL part. 605 * @param SelCS Selector part. 606 * @param Addr Address part. 607 * @param ppvFlat Where to store the flat address. 608 * @param pcBits Where to store the segment bitness (16/32/64). Optional. 609 */ 610 DECLINLINE(int) selmValidateAndConvertCSAddrRawMode(PVM pVM, PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr, 611 PRTGCPTR ppvFlat, uint32_t *pcBits) 795 612 { 796 613 NOREF(pVCpu); … … 850 667 return VERR_SELECTOR_NOT_PRESENT; 851 668 } 852 #endif /* !IN_RING0 */853 854 855 /** 856 * Validates and converts a GC selector based code address to a flat 857 * address when in protected/long mode using the standard algorithm.669 #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */ 670 671 672 /** 673 * Validates and converts a GC selector based code address to a flat address 674 * when in protected/long mode using the standard hidden selector registers 858 675 * 859 676 * @returns VBox status code. 860 * @param pVCpu Pointer to the VMCPU. 861 * @param SelCPL Current privilege level. Get this from SS - CS might be conforming! 862 * A full selector can be passed, we'll only use the RPL part. 863 * @param SelCS Selector part. 864 * @param Addr Address part. 865 * @param ppvFlat Where to store the flat address. 866 */ 867 DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pHidCS, 677 * @param pVCpu Pointer to the VMCPU. 678 * @param SelCPL Current privilege level. Get this from SS - CS might be 679 * conforming! A full selector can be passed, we'll only 680 * use the RPL part. 681 * @param SelCS Selector part. 682 * @param pSRegCS The full CS selector register. 683 * @param Addr The address (think IP/EIP/RIP). 684 * @param ppvFlat Where to store the flat address upon successful return. 685 */ 686 DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pSRegCS, 868 687 RTGCPTR Addr, PRTGCPTR ppvFlat) 869 688 { … … 871 690 * Check if present. 872 691 */ 873 if (p HidCS->Attr.n.u1Present)692 if (pSRegCS->Attr.n.u1Present) 874 693 { 875 694 /* 876 695 * Type check. 877 696 */ 878 if ( p HidCS->Attr.n.u1DescType == 1879 && (p HidCS->Attr.n.u4Type & X86_SEL_TYPE_CODE))697 if ( pSRegCS->Attr.n.u1DescType == 1 698 && (pSRegCS->Attr.n.u4Type & X86_SEL_TYPE_CODE)) 880 699 { 881 700 /* … … 883 702 */ 884 703 unsigned uLevel = RT_MAX(SelCPL & X86_SEL_RPL, SelCS & X86_SEL_RPL); 885 if ( !(p HidCS->Attr.n.u4Type & X86_SEL_TYPE_CONF)886 ? uLevel <= p HidCS->Attr.n.u2Dpl887 : uLevel >= p HidCS->Attr.n.u2Dpl /* hope I got this right now... */888 704 if ( !(pSRegCS->Attr.n.u4Type & X86_SEL_TYPE_CONF) 705 ? uLevel <= pSRegCS->Attr.n.u2Dpl 706 : uLevel >= pSRegCS->Attr.n.u2Dpl /* hope I got this right now... */ 707 ) 889 708 { 890 /* 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). */ 891 if ( pHidCS->Attr.n.u1Long 709 /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0 710 (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */ 711 if ( pSRegCS->Attr.n.u1Long 892 712 && CPUMIsGuestInLongMode(pVCpu)) 893 713 { … … 900 720 * final value. The granularity bit was included in its calculation. 901 721 */ 902 uint32_t u32Limit = p HidCS->u32Limit;722 uint32_t u32Limit = pSRegCS->u32Limit; 903 723 if ((RTGCUINTPTR)Addr <= u32Limit) 904 724 { 905 *ppvFlat = (RTGCPTR)( (RTGCUINTPTR)Addr + pHidCS->u64Base );725 *ppvFlat = Addr + pSRegCS->u64Base; 906 726 return VINF_SUCCESS; 907 727 } 728 908 729 return VERR_OUT_OF_SELECTOR_BOUNDS; 909 730 } 910 Log(("Invalid RPL Attr.n.u4Type=%x cpl=%x dpl=%x\n", pHidCS->Attr.n.u4Type, uLevel, pHidCS->Attr.n.u2Dpl)); 731 Log(("selmValidateAndConvertCSAddrHidden: Invalid RPL Attr.n.u4Type=%x cpl=%x dpl=%x\n", 732 pSRegCS->Attr.n.u4Type, uLevel, pSRegCS->Attr.n.u2Dpl)); 911 733 return VERR_INVALID_RPL; 912 734 } … … 917 739 918 740 919 #ifdef IN_RC920 741 /** 921 742 * Validates and converts a GC selector based code address to a flat address. 922 *923 * This is like SELMValidateAndConvertCSAddr + SELMIsSelector32Bit but with924 * invalid hidden CS data. It's customized for dealing efficiently with CS925 * at GC trap time.926 743 * 927 744 * @returns VBox status code. 928 745 * @param pVCpu Pointer to the VMCPU. 929 * @param eflags Current eflags930 * @param SelCPL Current privilege level. Get this from SS - CS might be931 * conforming! A full selector can be passed, we'll only746 * @param Efl Current EFLAGS. 747 * @param SelCPL Current privilege level. Get this from SS - CS might be 748 * conforming! A full selector can be passed, we'll only 932 749 * use the RPL part. 933 750 * @param SelCS Selector part. 934 * @param Addr Address part. 935 * @param ppvFlat Where to store the flat address. 936 * @param pcBits Where to store the 64-bit/32-bit/16-bit indicator. 937 */ 938 VMMDECL(int) SELMValidateAndConvertCSAddrGCTrap(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr, PRTGCPTR ppvFlat, uint32_t *pcBits) 939 { 940 if ( eflags.Bits.u1VM 751 * @param pSRegCS The full CS selector register. 752 * @param Addr The address (think IP/EIP/RIP). 753 * @param ppvFlat Where to store the flat address upon successful return. 754 */ 755 VMMDECL(int) SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS Efl, RTSEL SelCPL, RTSEL SelCS, PCPUMSELREG pSRegCS, 756 RTGCPTR Addr, PRTGCPTR ppvFlat) 757 { 758 if ( Efl.Bits.u1VM 941 759 || CPUMIsGuestInRealMode(pVCpu)) 942 { 943 *pcBits = 16; 944 return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, NULL, Addr, ppvFlat); 945 } 946 Assert(!CPUMAreHiddenSelRegsValid(pVCpu)); 947 return selmValidateAndConvertCSAddrStd(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, pcBits); 948 } 949 #endif /* IN_RC */ 950 951 952 /** 953 * Validates and converts a GC selector based code address to a flat address. 954 * 955 * @returns VBox status code. 956 * @param pVCpu Pointer to the VMCPU. 957 * @param eflags Current eflags 958 * @param SelCPL Current privilege level. Get this from SS - CS might be conforming! 959 * A full selector can be passed, we'll only use the RPL part. 960 * @param SelCS Selector part. 961 * @param pHiddenSel The hidden CS selector register. 962 * @param Addr Address part. 963 * @param ppvFlat Where to store the flat address. 964 */ 965 VMMDECL(int) SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pHiddenCSSel, 966 RTGCPTR Addr, PRTGCPTR ppvFlat) 967 { 968 if ( eflags.Bits.u1VM 969 || CPUMIsGuestInRealMode(pVCpu)) 970 return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, pHiddenCSSel, Addr, ppvFlat); 971 972 #ifdef IN_RING0 973 Assert(CPUMAreHiddenSelRegsValid(pVCpu)); 760 return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, pSRegCS, Addr, ppvFlat); 761 762 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 763 /* Use the hidden registers when possible, updating them if outdate. */ 764 if (!pSRegCS) 765 return selmValidateAndConvertCSAddrRawMode(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, NULL); 766 767 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSRegCS)) 768 CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSRegCS); 769 770 /* Undo ring compression. */ 771 if ((SelCPL & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM))) 772 SelCPL &= ~X86_SEL_RPL; 773 Assert(pSRegCS->Sel == SelCS); 774 if ((SelCS & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM))) 775 SelCS &= ~X86_SEL_RPL; 974 776 #else 975 /** @todo when we're in 16 bits mode, we should cut off the address as well? (like in selmValidateAndConvertCSAddrRealMode) */ 976 if (!CPUMAreHiddenSelRegsValid(pVCpu) || !pHiddenCSSel) 977 return selmValidateAndConvertCSAddrStd(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, NULL); 777 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSRegCS)); 778 Assert(pSRegCS->Sel == SelCS); 978 779 #endif 979 return selmValidateAndConvertCSAddrHidden(pVCpu, SelCPL, SelCS, pHiddenCSSel, Addr, ppvFlat); 980 } 981 982 983 #ifndef IN_RING0 984 /** 985 * Return the cpu mode corresponding to the (CS) selector 986 * 987 * @returns DISCPUMODE according to the selector type (16, 32 or 64 bits) 988 * @param pVM Pointer to the VM. 989 * @param pVCpu Pointer to the VMCPU. 990 * @param Sel The selector. 991 */ 992 static DISCPUMODE selmGetCpuModeFromSelector(PVM pVM, PVMCPU pVCpu, RTSEL Sel) 993 { 994 Assert(!CPUMAreHiddenSelRegsValid(pVCpu)); 995 996 /** @todo validate limit! */ 997 X86DESC Desc; 998 if (!(Sel & X86_SEL_LDT)) 999 Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT]; 1000 else 1001 { 1002 /** @todo handle LDT page(s) not present! */ 1003 PX86DESC paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper); 1004 Desc = paLDT[Sel >> X86_SEL_SHIFT]; 1005 } 1006 return (Desc.Gen.u1DefBig) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT; 1007 } 1008 #endif /* !IN_RING0 */ 1009 1010 1011 /** 1012 * Return the cpu mode corresponding to the (CS) selector 1013 * 1014 * @returns DISCPUMODE according to the selector type (16, 32 or 64 bits) 1015 * @param pVCpu Pointer to the VMCPU. 1016 * @param eflags Current eflags register 1017 * @param Sel The selector. 1018 * @param pHiddenSel The hidden selector register. 1019 */ 1020 VMMDECL(DISCPUMODE) SELMGetCpuModeFromSelector(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, PCCPUMSELREGHID pHiddenSel) 1021 { 1022 #ifdef IN_RING0 1023 Assert(CPUMAreHiddenSelRegsValid(pVCpu)); 1024 NOREF(eflags); NOREF(Sel); 1025 #else /* !IN_RING0 */ 1026 if (!CPUMAreHiddenSelRegsValid(pVCpu)) 1027 { 1028 /* 1029 * Deal with real & v86 mode first. 1030 */ 1031 if ( eflags.Bits.u1VM 1032 || CPUMIsGuestInRealMode(pVCpu)) 1033 return DISCPUMODE_16BIT; 1034 1035 return selmGetCpuModeFromSelector(pVCpu->CTX_SUFF(pVM), pVCpu, Sel); 1036 } 1037 #endif /* !IN_RING0 */ 1038 if ( pHiddenSel->Attr.n.u1Long 1039 && CPUMIsGuestInLongMode(pVCpu)) 1040 return DISCPUMODE_64BIT; 1041 1042 /* Else compatibility or 32 bits mode. */ 1043 return pHiddenSel->Attr.n.u1DefBig ? DISCPUMODE_32BIT : DISCPUMODE_16BIT; 780 781 return selmValidateAndConvertCSAddrHidden(pVCpu, SelCPL, SelCS, pSRegCS, Addr, ppvFlat); 1044 782 } 1045 783 … … 1084 822 1085 823 1086 #if ndef IN_RING0824 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 1087 825 /** 1088 826 * Gets ss:esp for ring1 in main Hypervisor's TSS. … … 1165 903 return VINF_SUCCESS; 1166 904 } 1167 #endif /* !IN_RING0 */905 #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */ 1168 906 1169 907 … … 1179 917 } 1180 918 1181 1182 #ifndef IN_RING0 919 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 1183 920 1184 921 /** … … 1254 991 } 1255 992 1256 #endif /* !IN_RING0 */993 #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */ 1257 994 1258 995 /** … … 1305 1042 pVM->selm.s.TssTrap08.cr3 = PGMGetInterRCCR3(pVM, pVCpu); 1306 1043 } 1044 -
trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp
r42165 r42186 341 341 342 342 343 #if ndef IN_RING0343 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 344 344 /** 345 345 * Forward trap or interrupt to the guest's handler … … 554 554 || !ss_r0 555 555 || (ss_r0 & X86_SEL_RPL) != ((dpl == 0) ? 1 : dpl) 556 || SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL,SELMTOFLAT_FLAGS_CPL1,556 || SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, SELMTOFLAT_FLAGS_CPL1, 557 557 (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS 558 558 ) … … 569 569 570 570 if ( eflags.Bits.u1VM /* illegal */ 571 || SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL,SELMTOFLAT_FLAGS_CPL1,571 || SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, SELMTOFLAT_FLAGS_CPL1, 572 572 (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS) 573 573 { … … 743 743 return VINF_EM_RAW_GUEST_TRAP; 744 744 } 745 #endif /* !IN_RING0 */745 #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */ 746 746 747 747 -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r42184 r42186 2428 2428 2429 2429 /* Disassemble manually to deal with segment prefixes. */ 2430 rc = EMInterpretDisas One(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, NULL);2430 rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL); 2431 2431 if (rc == VINF_SUCCESS) 2432 2432 { … … 2990 2990 * Only allow 32 & 64 bit code. 2991 2991 */ 2992 DISCPUMODE enmMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs); 2993 if (enmMode != DISCPUMODE_16BIT) 2992 if (CPUMGetGuestCodeBits(pVCpu) != 16) 2994 2993 { 2995 2994 PDISSTATE pDis = &pVCpu->hwaccm.s.DisState; 2996 int rc = EMInterpretDisas One(pVM, pVCpu, pRegFrame, pDis, NULL);2995 int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL); 2997 2996 if (RT_SUCCESS(rc) && pDis->pCurInstr->uOpcode == OP_INVLPG) 2998 2997 { -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r42184 r42186 3657 3657 LogFlow(("Real mode X86_XCPT_GP instruction emulation at %x:%RGv\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip)); 3658 3658 3659 rc2 = EMInterpretDisas One(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);3659 rc2 = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp); 3660 3660 if (RT_SUCCESS(rc2)) 3661 3661 { … … 4442 4442 /** @todo VMX_VMCS_EXIT_GUEST_LINEAR_ADDR contains the flat pointer operand of the instruction. */ 4443 4443 /** @todo VMX_VMCS32_RO_EXIT_INSTR_INFO also contains segment prefix info. */ 4444 rc2 = EMInterpretDisas One(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, NULL);4444 rc2 = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL); 4445 4445 if (RT_SUCCESS(rc)) 4446 4446 { -
trunk/src/VBox/VMM/VMMR3/CSAM.cpp
r41965 r42186 2295 2295 { 2296 2296 /* Assuming 32 bits code for now. */ 2297 Assert( SELMGetCpuModeFromSelector(VMMGetCpu0(pVM), pCtxCore->eflags, pCtxCore->cs.Sel, &pCtxCore->cs) == DISCPUMODE_32BIT);2297 Assert(CPUMGetGuestCodeBits(VMMGetCpu0(pVM)) == 32); 2298 2298 2299 2299 pInstrGC = SELMToFlat(pVM, DISSELREG_CS, pCtxCore, pInstrGC); -
trunk/src/VBox/VMM/VMMR3/EMRaw.cpp
r41939 r42186 685 685 { 686 686 rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip), 687 SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs) 688 == DISCPUMODE_32BIT ? PATMFL_CODE32 : 0); 687 CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0); 689 688 if (RT_SUCCESS(rc)) 690 689 { … … 936 935 { 937 936 int rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip), 938 ( SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs) 939 == DISCPUMODE_32BIT) ? PATMFL_CODE32 : 0); 937 CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0); 940 938 if (RT_SUCCESS(rc)) 941 939 { … … 1044 1042 if ( (pCtx->ss.Sel & X86_SEL_RPL) == 0 1045 1043 && !pCtx->eflags.Bits.u1VM 1046 && SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs) == DISCPUMODE_32BIT)1044 && CPUMGetGuestCodeBits(pVCpu) == 32) 1047 1045 { 1048 1046 STAM_PROFILE_START(&pVCpu->em.s.StatPrivEmu, a); -
trunk/src/VBox/VMM/VMMR3/HWACCM.cpp
r42033 r42186 1868 1868 PDISCPUSTATE pDis = &pVCpu->hwaccm.s.DisState; 1869 1869 uint32_t cbOp; 1870 int rc = EMInterpretDisas One(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);1870 int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp); 1871 1871 AssertRC(rc); 1872 1872 if ( rc == VINF_SUCCESS … … 1920 1920 1921 1921 pCtx->rip += cbOp; 1922 rc = EMInterpretDisas One(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);1922 rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp); 1923 1923 DBGFR3DisasInstrCurrentLog(pVCpu, "Following read"); 1924 1924 pCtx->rip = uSavedRip; … … 2041 2041 PDISCPUSTATE pDis = &pVCpu->hwaccm.s.DisState; 2042 2042 uint32_t cbOp; 2043 int rc = EMInterpretDisas One(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);2043 int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp); 2044 2044 AssertRC(rc); 2045 2045 if ( rc == VINF_SUCCESS -
trunk/src/VBox/VMM/VMMRC/PATMRC.cpp
r41965 r42186 507 507 } 508 508 509 DISCPUMODE enmCpuMode = SELMGetCpuModeFromSelector(VMMGetCpu0(pVM), pRegFrame->eflags, pRegFrame->cs.Sel, 0); 509 PVMCPU pVCpu = VMMGetCpu0(pVM); 510 DISCPUMODE enmCpuMode = CPUMGetGuestDisMode(pVCpu); 510 511 if (enmCpuMode != DISCPUMODE_32BIT) 511 512 { … … 516 517 #ifdef VBOX_WITH_IEM 517 518 VBOXSTRICTRC rcStrict; 518 rcStrict = IEMExecOneWithPrefetchedByPC( VMMGetCpu0(pVM), pRegFrame, pRegFrame->rip,519 rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, pRegFrame, pRegFrame->rip, 519 520 pRec->patch.aPrivInstr, pRec->patch.cbPrivInstr); 520 521 rc = VBOXSTRICTRC_TODO(rcStrict); … … 531 532 } 532 533 533 rc = EMInterpretInstructionDisasState( VMMGetCpu0(pVM), &cpu, pRegFrame, 0 /* not relevant here */,534 rc = EMInterpretInstructionDisasState(pVCpu, &cpu, pRegFrame, 0 /* not relevant here */, 534 535 EMCODETYPE_SUPERVISOR); 535 536 #endif -
trunk/src/VBox/VMM/VMMRC/TRPMRC.cpp
r41965 r42186 179 179 */ 180 180 DISSTATE Dis; 181 int rc = EMInterpretDisas One(pVM, pVCpu, pRegFrame, &Dis, NULL);181 int rc = EMInterpretDisasCurrent(pVM, pVCpu, &Dis, NULL); 182 182 if (rc == VINF_SUCCESS) 183 183 { -
trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
r41965 r42186 953 953 STAM_PROFILE_START(&pVM->trpm.s.StatTrap0dDisasm, a); 954 954 RTGCPTR PC; 955 uint32_t cBits; 956 int rc = SELMValidateAndConvertCSAddrGCTrap(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel, 957 pRegFrame->rip, &PC, &cBits); 955 int rc = SELMValidateAndConvertCSAddr(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel, &pRegFrame->cs, 956 pRegFrame->rip, &PC); 958 957 if (RT_FAILURE(rc)) 959 958 { -
trunk/src/VBox/VMM/include/EMHandleRCTmpl.h
r41906 r42186 113 113 rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip), 114 114 PATMFL_MMIO_ACCESS 115 | ( SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs) 116 == DISCPUMODE_32BIT ? PATMFL_CODE32 : 0)); 115 | (CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0)); 117 116 if (RT_FAILURE(rc)) 118 117 rc = emR3ExecuteInstruction(pVM, pVCpu, "MMIO");
Note:
See TracChangeset
for help on using the changeset viewer.