VirtualBox

Changeset 47247 in vbox


Ignore:
Timestamp:
Jul 19, 2013 10:01:36 AM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
87376
Message:

HMVMX: preserve SS.DPL and CS.L/D/G when the 'unusable' bit is set. SS.DPL = CPL, so we absolutely must preserve that.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/x86.h

    r47241 r47247  
    22302230#ifndef VBOX_FOR_DTRACE_LIB
    22312231/**
    2232  * Descriptor attributes.
     2232 * Descriptor attributes (as seen by VT-x).
    22332233 */
    22342234typedef struct X86DESCATTRBITS
     
    22542254     * clear byte. */
    22552255    unsigned    u1Granularity : 1;
    2256     /** 10 - Unusable selector, special Intel (VT-x only?) bit. */
     2256    /** 10 - "Unusable" selector, special Intel (VT-x only?) bit. */
    22572257    unsigned    u1Unusable : 1;
    22582258} X86DESCATTRBITS;
    22592259#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/** @}  */
    22602274
    22612275#pragma pack(1)
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r47243 r47247  
    6060/** Use the function table. */
    6161#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)
    6562
    6663/** Determine which tagged-TLB flush handler to use. */
     
    33733370               || (pCtx->cs.Attr.n.u1Granularity));
    33743371        /* 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?!? */
    33763373        if (pCtx->cs.Attr.n.u4Type == 9 || pCtx->cs.Attr.n.u4Type == 11)
    33773374            Assert(pCtx->cs.Attr.n.u2Dpl == pCtx->ss.Attr.n.u2Dpl);
     
    33893386            Assert(!pCtx->ss.Attr.n.u2Dpl);
    33903387        }
    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))
    33923389        {
    33933390            Assert((pCtx->ss.Sel & X86_SEL_RPL) == (pCtx->cs.Sel & X86_SEL_RPL));
     
    34023399        }
    34033400        /* 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))
    34053402        {
    34063403            Assert(pCtx->ds.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED);
     
    34163413                   || (pCtx->ds.Attr.n.u4Type & X86_SEL_TYPE_READ));
    34173414        }
    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))
    34193416        {
    34203417            Assert(pCtx->es.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED);
     
    34303427                   || (pCtx->es.Attr.n.u4Type & X86_SEL_TYPE_READ));
    34313428        }
    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))
    34333430        {
    34343431            Assert(pCtx->fs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED);
     
    34443441                   || (pCtx->fs.Attr.n.u4Type & X86_SEL_TYPE_READ));
    34453442        }
    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))
    34473444        {
    34483445            Assert(pCtx->gs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED);
     
    35603557         */
    35613558        if (!u32Access)
    3562             u32Access = HMVMX_SEL_UNUSABLE;
     3559            u32Access = X86DESCATTR_UNUSABLE;
    35633560    }
    35643561
    35653562    /* 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),
    35673564              ("Access bit not set for usable segment. idx=%#x sel=%#x attr %#x\n", idxBase, pSelReg, pSelReg->Attr.u));
    35683565
     
    36983695        AssertMsg(   (u32AccessRights & 0xf) == X86_SEL_TYPE_SYS_386_TSS_BUSY
    36993696                  || (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));
    37013698        Assert(!(u32AccessRights & RT_BIT(4)));                 /* System MBZ.*/
    37023699        Assert(u32AccessRights & RT_BIT(7));                    /* Present MB1.*/
     
    37383735        uint32_t u32Access = 0;
    37393736        if (!pMixedCtx->ldtr.Attr.u)
    3740             u32Access = HMVMX_SEL_UNUSABLE;
     3737            u32Access = X86DESCATTR_UNUSABLE;
    37413738        else
    37423739            u32Access = pMixedCtx->ldtr.Attr.u;
     
    37483745
    37493746        /* Validate. */
    3750         if (!(u32Access & HMVMX_SEL_UNUSABLE))
     3747        if (!(u32Access & X86DESCATTR_UNUSABLE))
    37513748        {
    37523749            Assert(!(pMixedCtx->ldtr.Sel & RT_BIT(2)));              /* TI MBZ. */
     
    54385435     * 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
    54395436     *       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 DPL
     5437     *       The Attr.u = X86DESCATTR_UNUSABLE works fine as long as nobody uses ring-1 or ring-2.  VT-x seems to set the DPL
    54415438     *       correctly in the attributes even when the unusable bit is set, we need to preseve the DPL or we get invalid guest
    54425439     *       state trouble.  Try bs2-cpu-hidden-regs-1.
    54435440     */
    5444     if (pSelReg->Attr.u & HMVMX_SEL_UNUSABLE)
     5441    if (pSelReg->Attr.u & X86DESCATTR_UNUSABLE)
    54455442    {
    54465443        Assert(idxSel != VMX_VMCS16_GUEST_FIELD_TR);          /* TR is the only selector that can never be unusable. */
    54475444        Log(("idxSel=%#x attr=%#x\n", idxSel, pSelReg->Attr.u));
    54485445
    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;
    54545452    }
    54555453    return VINF_SUCCESS;
     
    54585456
    54595457#ifdef VMX_USE_CACHED_VMCS_ACCESSES
    5460 #define VMXLOCAL_READ_SEG(Sel, CtxSel) \
     5458# define VMXLOCAL_READ_SEG(Sel, CtxSel) \
    54615459    hmR0VmxReadSegmentReg(pVCpu, VMX_VMCS16_GUEST_FIELD_##Sel, VMX_VMCS32_GUEST_##Sel##_LIMIT, \
    54625460                          VMX_VMCS_GUEST_##Sel##_BASE_CACHE_IDX, VMX_VMCS32_GUEST_##Sel##_ACCESS_RIGHTS, &pMixedCtx->CtxSel)
    54635461#else
    5464 #define VMXLOCAL_READ_SEG(Sel, CtxSel) \
     5462# define VMXLOCAL_READ_SEG(Sel, CtxSel) \
    54655463    hmR0VmxReadSegmentReg(pVCpu, VMX_VMCS16_GUEST_FIELD_##Sel, VMX_VMCS32_GUEST_##Sel##_LIMIT, \
    54665464                          VMX_VMCS_GUEST_##Sel##_BASE, VMX_VMCS32_GUEST_##Sel##_ACCESS_RIGHTS, &pMixedCtx->CtxSel)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette