Changeset 47247 in vbox
- Timestamp:
- Jul 19, 2013 10:01:36 AM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 87376
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/x86.h
r47241 r47247 2230 2230 #ifndef VBOX_FOR_DTRACE_LIB 2231 2231 /** 2232 * Descriptor attributes .2232 * Descriptor attributes (as seen by VT-x). 2233 2233 */ 2234 2234 typedef struct X86DESCATTRBITS … … 2254 2254 * clear byte. */ 2255 2255 unsigned u1Granularity : 1; 2256 /** 10 - Unusableselector, special Intel (VT-x only?) bit. */2256 /** 10 - "Unusable" selector, special Intel (VT-x only?) bit. */ 2257 2257 unsigned u1Unusable : 1; 2258 2258 } X86DESCATTRBITS; 2259 2259 #endif /* !VBOX_FOR_DTRACE_LIB */ 2260 2261 /** @name X86DESCATTR masks 2262 * @{ */ 2263 #define X86DESCATTR_TYPE UINT32_C(0x0000000f) 2264 #define X86DESCATTR_DT UINT32_C(0x00000010) 2265 #define X86DESCATTR_DPL UINT32_C(0x00000060) 2266 #define X86DESCATTR_P UINT32_C(0x00000800) 2267 #define X86DESCATTR_LIMIT_HIGH UINT32_C(0x00000f00) 2268 #define X86DESCATTR_AVL UINT32_C(0x00001000) 2269 #define X86DESCATTR_L UINT32_C(0x00002000) 2270 #define X86DESCATTR_D UINT32_C(0x00004000) 2271 #define X86DESCATTR_G UINT32_C(0x00008000) 2272 #define X86DESCATTR_UNUSABLE UINT32_C(0x00010000) 2273 /** @} */ 2260 2274 2261 2275 #pragma pack(1) -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r47243 r47247 60 60 /** Use the function table. */ 61 61 #define HMVMX_USE_FUNCTION_TABLE 62 63 /** This bit indicates the segment selector is unusable in VT-x. */64 #define HMVMX_SEL_UNUSABLE RT_BIT(16)65 62 66 63 /** Determine which tagged-TLB flush handler to use. */ … … 3373 3370 || (pCtx->cs.Attr.n.u1Granularity)); 3374 3371 /* CS cannot be loaded with NULL in protected mode. */ 3375 Assert(pCtx->cs.Attr.u && !(pCtx->cs.Attr.u & HMVMX_SEL_UNUSABLE)); /** @todo is this really true even for 64-bit CS?!? */3372 Assert(pCtx->cs.Attr.u && !(pCtx->cs.Attr.u & X86DESCATTR_UNUSABLE)); /** @todo is this really true even for 64-bit CS?!? */ 3376 3373 if (pCtx->cs.Attr.n.u4Type == 9 || pCtx->cs.Attr.n.u4Type == 11) 3377 3374 Assert(pCtx->cs.Attr.n.u2Dpl == pCtx->ss.Attr.n.u2Dpl); … … 3389 3386 Assert(!pCtx->ss.Attr.n.u2Dpl); 3390 3387 } 3391 if (pCtx->ss.Attr.u && !(pCtx->ss.Attr.u & HMVMX_SEL_UNUSABLE))3388 if (pCtx->ss.Attr.u && !(pCtx->ss.Attr.u & X86DESCATTR_UNUSABLE)) 3392 3389 { 3393 3390 Assert((pCtx->ss.Sel & X86_SEL_RPL) == (pCtx->cs.Sel & X86_SEL_RPL)); … … 3402 3399 } 3403 3400 /* DS, ES, FS, GS - only check for usable selectors, see hmR0VmxWriteSegmentReg(). */ 3404 if (pCtx->ds.Attr.u && !(pCtx->ds.Attr.u & HMVMX_SEL_UNUSABLE))3401 if (pCtx->ds.Attr.u && !(pCtx->ds.Attr.u & X86DESCATTR_UNUSABLE)) 3405 3402 { 3406 3403 Assert(pCtx->ds.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED); … … 3416 3413 || (pCtx->ds.Attr.n.u4Type & X86_SEL_TYPE_READ)); 3417 3414 } 3418 if (pCtx->es.Attr.u && !(pCtx->es.Attr.u & HMVMX_SEL_UNUSABLE))3415 if (pCtx->es.Attr.u && !(pCtx->es.Attr.u & X86DESCATTR_UNUSABLE)) 3419 3416 { 3420 3417 Assert(pCtx->es.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED); … … 3430 3427 || (pCtx->es.Attr.n.u4Type & X86_SEL_TYPE_READ)); 3431 3428 } 3432 if (pCtx->fs.Attr.u && !(pCtx->fs.Attr.u & HMVMX_SEL_UNUSABLE))3429 if (pCtx->fs.Attr.u && !(pCtx->fs.Attr.u & X86DESCATTR_UNUSABLE)) 3433 3430 { 3434 3431 Assert(pCtx->fs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED); … … 3444 3441 || (pCtx->fs.Attr.n.u4Type & X86_SEL_TYPE_READ)); 3445 3442 } 3446 if (pCtx->gs.Attr.u && !(pCtx->gs.Attr.u & HMVMX_SEL_UNUSABLE))3443 if (pCtx->gs.Attr.u && !(pCtx->gs.Attr.u & X86DESCATTR_UNUSABLE)) 3447 3444 { 3448 3445 Assert(pCtx->gs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED); … … 3560 3557 */ 3561 3558 if (!u32Access) 3562 u32Access = HMVMX_SEL_UNUSABLE;3559 u32Access = X86DESCATTR_UNUSABLE; 3563 3560 } 3564 3561 3565 3562 /* Validate segment access rights. Refer to Intel spec. "26.3.1.2 Checks on Guest Segment Registers". */ 3566 AssertMsg((u32Access & HMVMX_SEL_UNUSABLE) || (u32Access & X86_SEL_TYPE_ACCESSED),3563 AssertMsg((u32Access & X86DESCATTR_UNUSABLE) || (u32Access & X86_SEL_TYPE_ACCESSED), 3567 3564 ("Access bit not set for usable segment. idx=%#x sel=%#x attr %#x\n", idxBase, pSelReg, pSelReg->Attr.u)); 3568 3565 … … 3698 3695 AssertMsg( (u32AccessRights & 0xf) == X86_SEL_TYPE_SYS_386_TSS_BUSY 3699 3696 || (u32AccessRights & 0xf) == X86_SEL_TYPE_SYS_286_TSS_BUSY, ("TSS is not busy!? %#x\n", u32AccessRights)); 3700 AssertMsg(!(u32AccessRights & HMVMX_SEL_UNUSABLE), ("TR unusable bit is not clear!? %#x\n", u32AccessRights));3697 AssertMsg(!(u32AccessRights & X86DESCATTR_UNUSABLE), ("TR unusable bit is not clear!? %#x\n", u32AccessRights)); 3701 3698 Assert(!(u32AccessRights & RT_BIT(4))); /* System MBZ.*/ 3702 3699 Assert(u32AccessRights & RT_BIT(7)); /* Present MB1.*/ … … 3738 3735 uint32_t u32Access = 0; 3739 3736 if (!pMixedCtx->ldtr.Attr.u) 3740 u32Access = HMVMX_SEL_UNUSABLE;3737 u32Access = X86DESCATTR_UNUSABLE; 3741 3738 else 3742 3739 u32Access = pMixedCtx->ldtr.Attr.u; … … 3748 3745 3749 3746 /* Validate. */ 3750 if (!(u32Access & HMVMX_SEL_UNUSABLE))3747 if (!(u32Access & X86DESCATTR_UNUSABLE)) 3751 3748 { 3752 3749 Assert(!(pMixedCtx->ldtr.Sel & RT_BIT(2))); /* TI MBZ. */ … … 5438 5435 * bird: This isn't quite as simple. VT-x and VBox(!) requires the DPL for SS to be the the same as CPL. In 64-bit mode it 5439 5436 * is possible (int/trap/xxx injects does this when switching rings) to load SS with a NULL selector and RPL=CPL. 5440 * The Attr.u = HMVMX_SEL_UNUSABLE works fine as long as nobody uses ring-1 or ring-2. VT-x seems to set the DPL5437 * The Attr.u = X86DESCATTR_UNUSABLE works fine as long as nobody uses ring-1 or ring-2. VT-x seems to set the DPL 5441 5438 * correctly in the attributes even when the unusable bit is set, we need to preseve the DPL or we get invalid guest 5442 5439 * state trouble. Try bs2-cpu-hidden-regs-1. 5443 5440 */ 5444 if (pSelReg->Attr.u & HMVMX_SEL_UNUSABLE)5441 if (pSelReg->Attr.u & X86DESCATTR_UNUSABLE) 5445 5442 { 5446 5443 Assert(idxSel != VMX_VMCS16_GUEST_FIELD_TR); /* TR is the only selector that can never be unusable. */ 5447 5444 Log(("idxSel=%#x attr=%#x\n", idxSel, pSelReg->Attr.u)); 5448 5445 5449 #if 0 /** @todo Is there any code which will freak out if we do this for all? Better track it down and fix. */ 5450 pSelReg->Attr.u &= HMVMX_SEL_UNUSABLE | (UINT32_C(3) << 5); 5451 #else 5452 pSelReg->Attr.u = HMVMX_SEL_UNUSABLE; 5453 #endif 5446 if (idxSel == VMX_VMCS16_GUEST_FIELD_SS) 5447 pSelReg->Attr.u &= X86DESCATTR_UNUSABLE | X86DESCATTR_DPL; 5448 else if (idxSel == VMX_VMCS16_GUEST_FIELD_CS) 5449 pSelReg->Attr.u &= X86DESCATTR_UNUSABLE | X86DESCATTR_L | X86DESCATTR_D | X86DESCATTR_G; 5450 else 5451 pSelReg->Attr.u = X86DESCATTR_UNUSABLE; 5454 5452 } 5455 5453 return VINF_SUCCESS; … … 5458 5456 5459 5457 #ifdef VMX_USE_CACHED_VMCS_ACCESSES 5460 # define VMXLOCAL_READ_SEG(Sel, CtxSel) \5458 # define VMXLOCAL_READ_SEG(Sel, CtxSel) \ 5461 5459 hmR0VmxReadSegmentReg(pVCpu, VMX_VMCS16_GUEST_FIELD_##Sel, VMX_VMCS32_GUEST_##Sel##_LIMIT, \ 5462 5460 VMX_VMCS_GUEST_##Sel##_BASE_CACHE_IDX, VMX_VMCS32_GUEST_##Sel##_ACCESS_RIGHTS, &pMixedCtx->CtxSel) 5463 5461 #else 5464 # define VMXLOCAL_READ_SEG(Sel, CtxSel) \5462 # define VMXLOCAL_READ_SEG(Sel, CtxSel) \ 5465 5463 hmR0VmxReadSegmentReg(pVCpu, VMX_VMCS16_GUEST_FIELD_##Sel, VMX_VMCS32_GUEST_##Sel##_LIMIT, \ 5466 5464 VMX_VMCS_GUEST_##Sel##_BASE, VMX_VMCS32_GUEST_##Sel##_ACCESS_RIGHTS, &pMixedCtx->CtxSel)
Note:
See TracChangeset
for help on using the changeset viewer.