VirtualBox

Changeset 42427 in vbox


Ignore:
Timestamp:
Jul 26, 2012 11:48:01 PM (12 years ago)
Author:
vboxsync
Message:

VMM: Fixed some selector arithmetic, introducing a new constand and renaming and old one to make things clearer. Also added CPUMGetGuestLdtrEx and make some (but not all) of SELM use this instead of shadow GDT.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpum.h

    r42420 r42427  
    9191VMMDECL(RTSEL)      CPUMGetGuestTR(PVMCPU pVCpu, PCPUMSELREGHID pHidden);
    9292VMMDECL(RTSEL)      CPUMGetGuestLDTR(PVMCPU pVCpu);
     93VMMDECL(RTSEL)      CPUMGetGuestLdtrEx(PVMCPU pVCpu, uint64_t *pGCPtrBase, uint32_t *pcbLimit);
    9394VMMDECL(uint64_t)   CPUMGetGuestCR0(PVMCPU pVCpu);
    9495VMMDECL(uint64_t)   CPUMGetGuestCR2(PVMCPU pVCpu);
  • trunk/include/VBox/vmm/cpumctx.h

    r42415 r42427  
    8686     && (   (a_pSelReg)->ValidSel == (a_pSelReg)->Sel \
    8787         || (   (a_pVCpu) /*!= NULL*/ \
    88              && (a_pSelReg)->ValidSel == ((a_pSelReg)->Sel & X86_SEL_MASK_RPL) \
     88             && (a_pSelReg)->ValidSel == ((a_pSelReg)->Sel & X86_SEL_MASK_OFF_RPL) \
    8989             && ((a_pSelReg)->Sel      & X86_SEL_RPL) == 1 \
    9090             && ((a_pSelReg)->ValidSel & X86_SEL_RPL) == 0 \
  • trunk/include/VBox/vmm/selm.h

    r42407 r42427  
    8080VMMDECL(int)            SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS,
    8181                                                     PCPUMSELREG pSRegCS, RTGCPTR Addr, PRTGCPTR ppvFlat);
    82 VMMDECL(int)            SELMGetLDTFromSel(PVM pVM, RTSEL SelLdt, PRTGCPTR ppvLdt, unsigned *pcbLimit);
    8382#ifdef VBOX_WITH_RAW_MODE
    8483VMM_INT_DECL(void)      SELMLoadHiddenSelectorReg(PVMCPU pVCpu, PCCPUMCTX pCtx, PCPUMSELREG pSReg);
  • trunk/include/iprt/x86.h

    r42407 r42427  
    29552955 * The shift used to convert a selector from and to index an index (C).
    29562956 */
    2957 #define X86_SEL_SHIFT       3
     2957#define X86_SEL_SHIFT           3
    29582958
    29592959/**
    29602960 * The mask used to mask off the table indicator and RPL of an selector.
    29612961 */
    2962 #define X86_SEL_MASK        0xfff8U
     2962#define X86_SEL_MASK            0xfff8U
    29632963
    29642964/**
    29652965 * The mask used to mask off the RPL of an selector.
    2966  */
    2967 #define X86_SEL_MASK_RPL    0xfffcU
     2966 * This is suitable for checking for NULL selectors.
     2967 */
     2968#define X86_SEL_MASK_OFF_RPL    0xfffcU
    29682969
    29692970/**
    29702971 * The bit indicating that a selector is in the LDT and not in the GDT.
    29712972 */
    2972 #define X86_SEL_LDT         0x0004U
     2973#define X86_SEL_LDT             0x0004U
     2974
    29732975/**
    29742976 * The bit mask for getting the RPL of a selector.
    29752977 */
    2976 #define X86_SEL_RPL         0x0003U
     2978#define X86_SEL_RPL             0x0003U
     2979
     2980/**
     2981 * The mask covering both RPL and LDT.
     2982 * This is incidentally the same as sizeof(X86DESC) - 1, so good for limit
     2983 * checks.
     2984 */
     2985#define X86_SEL_RPL_LDT         0x0007U
    29772986
    29782987/** @} */
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r42420 r42427  
    116116    {
    117117        /* Protected mode - get it from the selector descriptor tables. */
    118         if (!(pSReg->Sel & X86_SEL_MASK))
     118        if (!(pSReg->Sel & X86_SEL_MASK_OFF_RPL))
    119119        {
    120120            Assert(!CPUMIsGuestInLongMode(pVCpu));
     
    13031303VMMDECL(RTSEL) CPUMGetGuestLDTR(PVMCPU pVCpu)
    13041304{
     1305    return pVCpu->cpum.s.Guest.ldtr.Sel;
     1306}
     1307
     1308
     1309VMMDECL(RTSEL) CPUMGetGuestLdtrEx(PVMCPU pVCpu, uint64_t *pGCPtrBase, uint32_t *pcbLimit)
     1310{
     1311    *pGCPtrBase = pVCpu->cpum.s.Guest.ldtr.u64Base;
     1312    *pcbLimit   = pVCpu->cpum.s.Guest.ldtr.u32Limit;
    13051313    return pVCpu->cpum.s.Guest.ldtr.Sel;
    13061314}
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r42407 r42427  
    15141514    /* Null selectors are not allowed (we're not called for dispatching
    15151515       interrupts with SS=0 in long mode). */
    1516     if (!(NewSS & (X86_SEL_MASK | X86_SEL_LDT)))
     1516    if (!(NewSS & X86_SEL_MASK_OFF_RPL))
    15171517    {
    15181518        Log(("iemMiscValidateNewSSandRsp: #x - null selector -> #GP(0)\n", NewSS));
     
    18631863    /* A null CS is bad. */
    18641864    RTSEL NewCS = Idte.Gate.u16Sel;
    1865     if (!(NewCS & (X86_SEL_MASK | X86_SEL_LDT)))
     1865    if (!(NewCS & X86_SEL_MASK_OFF_RPL))
    18661866    {
    18671867        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x -> #GP\n", u8Vector, NewCS));
     
    18821882    {
    18831883        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - system selector (%#x) -> #GP\n", u8Vector, NewCS, DescCS.Legacy.Gen.u4Type));
    1884         return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
     1884        return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
    18851885    }
    18861886    if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE))
    18871887    {
    18881888        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - data selector (%#x) -> #GP\n", u8Vector, NewCS, DescCS.Legacy.Gen.u4Type));
    1889         return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
     1889        return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
    18901890    }
    18911891
     
    18991899        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - DPL (%d) > CPL (%d) -> #GP\n",
    19001900             u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
    1901         return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
     1901        return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
    19021902    }
    19031903    /** @todo is the RPL of the interrupt/trap gate descriptor checked? */
     
    19131913        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - DPL (%d) > CPL (%d) -> #GP\n",
    19141914             u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
    1915         return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
     1915        return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
    19161916    }
    19171917
     
    58165816    {
    58175817        if (   !pCtx->ldtr.Attr.n.u1Present
    5818             || (uSel | 0x7U) > pCtx->ldtr.u32Limit )
     5818            || (uSel | X86_SEL_RPL_LDT) > pCtx->ldtr.u32Limit )
    58195819        {
    58205820            Log(("iemMemFetchSelDesc: LDT selector %#x is out of bounds (%3x) or ldtr is NP (%#x)\n",
     
    58295829    else
    58305830    {
    5831         if ((uSel | 0x7U) > pCtx->gdtr.cbGdt)
     5831        if ((uSel | X86_SEL_RPL_LDT) > pCtx->gdtr.cbGdt)
    58325832        {
    58335833            Log(("iemMemFetchSelDesc: GDT selector %#x is out of bounds (%3x)\n", uSel, pCtx->gdtr.cbGdt));
     
    58485848            || pDesc->Legacy.Gen.u1DescType)
    58495849            pDesc->Long.au64[1] = 0;
    5850         else if ((uint32_t)(uSel & X86_SEL_MASK) + 15 < (uSel & X86_SEL_LDT ? pCtx->ldtr.u32Limit : pCtx->gdtr.cbGdt))
    5851             rcStrict = iemMemFetchSysU64(pIemCpu, &pDesc->Legacy.u, UINT8_MAX, GCPtrBase + (uSel & X86_SEL_MASK));
     5850        else if ((uint32_t)(uSel | X86_SEL_RPL_LDT) + 8 <= (uSel & X86_SEL_LDT ? pCtx->ldtr.u32Limit : pCtx->gdtr.cbGdt))
     5851            rcStrict = iemMemFetchSysU64(pIemCpu, &pDesc->Long.au64[1], UINT8_MAX, GCPtrBase + (uSel | X86_SEL_RPL_LDT) + 1);
    58525852        else
    58535853        {
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r42407 r42427  
    818818{
    819819    Assert(enmBranch == IEMBRANCH_JUMP || enmBranch == IEMBRANCH_CALL);
    820     Assert((uSel & (X86_SEL_MASK | X86_SEL_LDT)));
     820    Assert((uSel & X86_SEL_MASK_OFF_RPL));
    821821
    822822    if (IEM_IS_LONG_MODE(pIemCpu))
     
    913913     * Protected mode. Need to parse the specified descriptor...
    914914     */
    915     if (!(uSel & (X86_SEL_MASK | X86_SEL_LDT)))
     915    if (!(uSel & X86_SEL_MASK_OFF_RPL))
    916916    {
    917917        Log(("jmpf %04x:%08RX64 -> invalid selector, #GP(0)\n", uSel, offSeg));
     
    10151015    /* commit */
    10161016    pCtx->rip = offSeg;
    1017     pCtx->cs.Sel         = uSel & (X86_SEL_MASK | X86_SEL_LDT);
     1017    pCtx->cs.Sel         = uSel & X86_SEL_MASK_OFF_RPL;
    10181018    pCtx->cs.Sel        |= pIemCpu->uCpl; /** @todo is this right for conforming segs? or in general? */
    10191019    pCtx->cs.ValidSel    = pCtx->cs.Sel;
     
    10961096     * Protected mode. Need to parse the specified descriptor...
    10971097     */
    1098     if (!(uSel & (X86_SEL_MASK | X86_SEL_LDT)))
     1098    if (!(uSel & X86_SEL_MASK_OFF_RPL))
    10991099    {
    11001100        Log(("callf %04x:%08RX64 -> invalid selector, #GP(0)\n", uSel, offSeg));
     
    12361236    /* commit */
    12371237    pCtx->rip = offSeg;
    1238     pCtx->cs.Sel         = uSel & (X86_SEL_MASK | X86_SEL_LDT);
     1238    pCtx->cs.Sel         = uSel & X86_SEL_MASK_OFF_RPL;
    12391239    pCtx->cs.Sel        |= pIemCpu->uCpl;
    12401240    pCtx->cs.ValidSel    = pCtx->cs.Sel;
     
    13231323     * Protected mode is complicated, of course.
    13241324     */
    1325     if (!(uNewCs & (X86_SEL_MASK | X86_SEL_LDT)))
     1325    if (!(uNewCs & X86_SEL_MASK_OFF_RPL))
    13261326    {
    13271327        Log(("retf %04x:%08RX64 -> invalid selector, #GP(0)\n", uNewCs, uNewRip));
     
    14171417           and read the selector. */
    14181418        IEMSELDESC DescSs;
    1419         if (!(uNewOuterSs & (X86_SEL_MASK | X86_SEL_LDT)))
     1419        if (!(uNewOuterSs & X86_SEL_MASK_OFF_RPL))
    14201420        {
    14211421            if (   !DescCs.Legacy.Gen.u1Long
     
    19611961             */
    19621962            /* Read the CS descriptor. */
    1963             if (!(uNewCs & (X86_SEL_MASK | X86_SEL_LDT)))
     1963            if (!(uNewCs & X86_SEL_MASK_OFF_RPL))
    19641964            {
    19651965                Log(("iret %04x:%08x -> invalid CS selector, #GP(0)\n", uNewCs, uNewEip));
     
    20372037
    20382038                /* Read the SS descriptor. */
    2039                 if (!(uNewSS & (X86_SEL_MASK | X86_SEL_LDT)))
     2039                if (!(uNewSS & X86_SEL_MASK_OFF_RPL))
    20402040                {
    20412041                    Log(("iret %04x:%08x/%04x:%08x -> invalid SS selector, #GP(0)\n", uNewCs, uNewEip, uNewSS, uNewESP));
     
    22812281     * FS and GS.  If not null, then we have to load and parse the descriptor.
    22822282     */
    2283     if (!(uSel & (X86_SEL_MASK | X86_SEL_LDT)))
     2283    if (!(uSel & X86_SEL_MASK_OFF_RPL))
    22842284    {
    22852285        if (iSegReg == X86_SREG_SS)
     
    26592659     * Now, loading a NULL selector is easy.
    26602660     */
    2661     if ((uNewLdt & X86_SEL_MASK) == 0)
     2661    if (!(uNewLdt & X86_SEL_MASK_OFF_RPL))
    26622662    {
    26632663        Log(("lldt %04x: Loading NULL selector.\n",  uNewLdt));
     
    26892689    {
    26902690        Log(("lldt %#x - not system selector (type %x) -> #GP\n", uNewLdt, Desc.Legacy.Gen.u4Type));
    2691         return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK);
     2691        return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK_OFF_RPL);
    26922692    }
    26932693    if (Desc.Legacy.Gen.u4Type != X86_SEL_TYPE_SYS_LDT)
    26942694    {
    26952695        Log(("lldt %#x - not LDT selector (type %x) -> #GP\n", uNewLdt, Desc.Legacy.Gen.u4Type));
    2696         return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK);
     2696        return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK_OFF_RPL);
    26972697    }
    26982698    uint64_t u64Base;
     
    27042704        {
    27052705            Log(("lldt %#x - u5Zeros=%#x -> #GP\n", uNewLdt, Desc.Long.Gen.u5Zeros));
    2706             return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK);
     2706            return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK_OFF_RPL);
    27072707        }
    27082708
     
    27112711        {
    27122712            Log(("lldt %#x - non-canonical base address %#llx -> #GP\n", uNewLdt, u64Base));
    2713             return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK);
     2713            return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & X86_SEL_MASK_OFF_RPL);
    27142714        }
    27152715    }
     
    27272727/** @todo check if the actual value is loaded or if the RPL is dropped */
    27282728    if (!IEM_VERIFICATION_ENABLED(pIemCpu))
    2729         CPUMSetGuestLDTR(IEMCPU_TO_VMCPU(pIemCpu), uNewLdt & X86_SEL_MASK);
     2729        CPUMSetGuestLDTR(IEMCPU_TO_VMCPU(pIemCpu), uNewLdt & X86_SEL_MASK_OFF_RPL);
    27302730    else
    2731         pCtx->ldtr.Sel  = uNewLdt & X86_SEL_MASK;
    2732     pCtx->ldtr.ValidSel = uNewLdt & X86_SEL_MASK;
     2731        pCtx->ldtr.Sel  = uNewLdt & X86_SEL_MASK_OFF_RPL;
     2732    pCtx->ldtr.ValidSel = uNewLdt & X86_SEL_MASK_OFF_RPL;
    27332733    pCtx->ldtr.fFlags   = CPUMSELREG_FLAGS_VALID;
    27342734    pCtx->ldtr.Attr.u   = X86DESC_GET_HID_ATTR(&Desc.Legacy);
     
    27682768        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewTr);
    27692769    }
    2770     if ((uNewTr & X86_SEL_MASK) == 0)
     2770    if (!(uNewTr & X86_SEL_MASK_OFF_RPL))
    27712771    {
    27722772        Log(("ltr %04x - NULL selector -> #GP(0)\n", uNewTr));
     
    27862786    {
    27872787        Log(("ltr %#x - not system selector (type %x) -> #GP\n", uNewTr, Desc.Legacy.Gen.u4Type));
    2788         return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK);
     2788        return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK_OFF_RPL);
    27892789    }
    27902790    if (   Desc.Legacy.Gen.u4Type != X86_SEL_TYPE_SYS_386_TSS_AVAIL /* same as AMD64_SEL_TYPE_SYS_TSS_AVAIL */
     
    27932793    {
    27942794        Log(("ltr %#x - not an available TSS selector (type %x) -> #GP\n", uNewTr, Desc.Legacy.Gen.u4Type));
    2795         return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK);
     2795        return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK_OFF_RPL);
    27962796    }
    27972797    uint64_t u64Base;
     
    28032803        {
    28042804            Log(("ltr %#x - u5Zeros=%#x -> #GP\n", uNewTr, Desc.Long.Gen.u5Zeros));
    2805             return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK);
     2805            return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK_OFF_RPL);
    28062806        }
    28072807
     
    28102810        {
    28112811            Log(("ltr %#x - non-canonical base address %#llx -> #GP\n", uNewTr, u64Base));
    2812             return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK);
     2812            return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & X86_SEL_MASK_OFF_RPL);
    28132813        }
    28142814    }
     
    28482848/** @todo check if the actual value is loaded or if the RPL is dropped */
    28492849    if (!IEM_VERIFICATION_ENABLED(pIemCpu))
    2850         CPUMSetGuestTR(IEMCPU_TO_VMCPU(pIemCpu), uNewTr & X86_SEL_MASK);
     2850        CPUMSetGuestTR(IEMCPU_TO_VMCPU(pIemCpu), uNewTr & X86_SEL_MASK_OFF_RPL);
    28512851    else
    2852         pCtx->tr.Sel  = uNewTr & X86_SEL_MASK;
    2853     pCtx->tr.ValidSel = uNewTr & X86_SEL_MASK;
     2852        pCtx->tr.Sel  = uNewTr & X86_SEL_MASK_OFF_RPL;
     2853    pCtx->tr.ValidSel = uNewTr & X86_SEL_MASK_OFF_RPL;
    28542854    pCtx->tr.fFlags   = CPUMSELREG_FLAGS_VALID;
    28552855    pCtx->tr.Attr.u   = X86DESC_GET_HID_ATTR(&Desc.Legacy);
  • trunk/src/VBox/VMM/VMMAll/SELMAll.cpp

    r42420 r42427  
    340340    {
    341341        if (   !(fFlags & SELMTOFLAT_FLAGS_HYPER)
    342             && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
     342            && (Sel | X86_SEL_RPL_LDT) > pVM->selm.s.GuestGdtr.cbGdt)
    343343            return VERR_INVALID_SELECTOR;
    344344        Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
     
    346346    else
    347347    {
    348         if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit)
     348        if ((Sel | X86_SEL_RPL_LDT) > pVM->selm.s.cbLdtLimit)
    349349            return VERR_INVALID_SELECTOR;
    350350
    351351        /** @todo handle LDT page(s) not present! */
    352         PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
     352        PX86DESC paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    353353        Desc = paLDT[Sel >> X86_SEL_SHIFT];
    354354    }
     
    10321032    CPUMSELREGHID trHid;
    10331033    RTSEL tr = CPUMGetGuestTR(pVCpu, &trHid);
    1034     if (!(tr & X86_SEL_MASK))
     1034    if (!(tr & X86_SEL_MASK_OFF_RPL))
    10351035        return VERR_SELM_NO_TSS;
    10361036
  • trunk/src/VBox/VMM/VMMR3/SELM.cpp

    r42418 r42427  
    10681068     */
    10691069    RTSEL SelLdt = CPUMGetGuestLDTR(pVCpu);
    1070     if ((SelLdt & X86_SEL_MASK) == 0)
     1070    if (!(SelLdt & X86_SEL_MASK_OFF_RPL))
    10711071    {
    10721072        /* ldtr = 0 - update hyper LDTR and deregister any active handler. */
     
    10851085     * Get the LDT selector.
    10861086     */
     1087/** @todo this is wrong, use CPUMGetGuestLdtrEx */
    10871088    PX86DESC    pDesc    = &pVM->selm.s.paGdtR3[SelLdt >> X86_SEL_SHIFT];
    10881089    RTGCPTR     GCPtrLdt = X86DESC_BASE(pDesc);
     
    12931294    for (uint32_t iSReg = 0; iSReg < X86_SREG_COUNT; iSReg++)
    12941295    {
    1295         RTSEL const Sel = paSReg[iSReg].Sel & (X86_SEL_MASK | X86_SEL_LDT);
    1296         if (Sel & (X86_SEL_MASK | X86_SEL_LDT))
     1296        RTSEL const Sel = paSReg[iSReg].Sel;
     1297        if (Sel & X86_SEL_MASK_OFF_RPL)
    12971298        {
    12981299            /* Get the shadow descriptor entry corresponding to this. */
     
    15531554     *       make sure cbTss is 0.
    15541555     */
     1556/** @todo use the hidden bits, not shadow GDT. */
    15551557    CPUMSELREGHID   trHid;
    15561558    RTSEL           SelTss   = CPUMGetGuestTR(pVCpu, &trHid);
    15571559    RTGCPTR         GCPtrTss = trHid.u64Base;
    15581560    uint32_t        cbTss    = trHid.u32Limit;
    1559     Assert(     (SelTss & X86_SEL_MASK)
    1560            ||   (cbTss == 0 && GCPtrTss == 0 && trHid.Attr.u == 0 /* TR=0 */)
    1561            ||   (cbTss == 0xffff && GCPtrTss == 0 && trHid.Attr.n.u1Present && trHid.Attr.n.u4Type == X86_SEL_TYPE_SYS_386_TSS_BUSY /* RESET */));
    1562     if (SelTss & X86_SEL_MASK)
     1561    Assert(   (SelTss & X86_SEL_MASK_OFF_RPL)
     1562           || (cbTss == 0 && GCPtrTss == 0 && trHid.Attr.u == 0 /* TR=0 */)
     1563           || (cbTss == 0xffff && GCPtrTss == 0 && trHid.Attr.n.u1Present && trHid.Attr.n.u4Type == X86_SEL_TYPE_SYS_386_TSS_BUSY /* RESET */));
     1564    if (SelTss & X86_SEL_MASK_OFF_RPL)
    15631565    {
    15641566        Assert(!(SelTss & X86_SEL_LDT));
     
    17931795     */
    17941796    RTSEL SelLdt = CPUMGetGuestLDTR(pVCpu);
    1795     if ((SelLdt & X86_SEL_MASK) == 0)
     1797    if ((SelLdt & X86_SEL_MASK_OFF_RPL) == 0)
    17961798        return VINF_SUCCESS;
     1799    Assert(!(SelLdt & X86_SEL_LDT));
    17971800    if (SelLdt > GDTR.cbGdt)
    17981801    {
     
    18861889    RTGCPTR         GCPtrTss = trHid.u64Base;
    18871890    uint32_t        cbTss    = trHid.u32Limit;
    1888     Assert(     (SelTss & X86_SEL_MASK)
    1889            ||   (cbTss == 0 && GCPtrTss == 0 && trHid.Attr.u == 0 /* TR=0 */)
    1890            ||   (cbTss == 0xffff && GCPtrTss == 0 && trHid.Attr.n.u1Present && trHid.Attr.n.u4Type == X86_SEL_TYPE_SYS_386_TSS_BUSY /* RESET */));
    1891     if (SelTss & X86_SEL_MASK)
     1891    Assert(   (SelTss & X86_SEL_MASK_OFF_RPL)
     1892           || (cbTss == 0 && GCPtrTss == 0 && trHid.Attr.u == 0 /* TR=0 */)
     1893           || (cbTss == 0xffff && GCPtrTss == 0 && trHid.Attr.n.u1Present && trHid.Attr.n.u4Type == X86_SEL_TYPE_SYS_386_TSS_BUSY /* RESET */));
     1894    if (SelTss & X86_SEL_MASK_OFF_RPL)
    18921895    {
    18931896        AssertReturn(!(SelTss & X86_SEL_LDT), false);
     
    20072010
    20082011/**
    2009  * Returns flat address and limit of LDT by LDT selector from guest GDTR.
    2010  *
    2011  * Fully validate selector.
    2012  *
    2013  * @returns VBox status.
    2014  * @param   pVM       Pointer to the VM.
    2015  * @param   SelLdt    LDT selector.
    2016  * @param   ppvLdt    Where to store the flat address of LDT.
    2017  * @param   pcbLimit  Where to store LDT limit.
    2018  */
    2019 VMMDECL(int) SELMGetLDTFromSel(PVM pVM, RTSEL SelLdt, PRTGCPTR ppvLdt, unsigned *pcbLimit)
    2020 {
    2021     PVMCPU pVCpu = VMMGetCpu(pVM);
    2022 
    2023     /* Get guest GDTR. */
    2024     VBOXGDTR GDTR;
    2025     CPUMGetGuestGDTR(pVCpu, &GDTR);
    2026 
    2027     /* Check selector TI and GDT limit. */
    2028     if (   (SelLdt & X86_SEL_LDT)
    2029         || SelLdt > GDTR.cbGdt)
    2030         return VERR_INVALID_SELECTOR;
    2031 
    2032     /* Read descriptor from GC. */
    2033     X86DESC Desc;
    2034     int rc = PGMPhysSimpleReadGCPtr(pVCpu, (void *)&Desc, (RTGCPTR)(GDTR.pGdt + (SelLdt & X86_SEL_MASK)), sizeof(Desc));
    2035     if (RT_FAILURE(rc))
    2036     {
    2037         /* fatal */
    2038         Log(("Can't read LDT descriptor for selector=%04X\n", SelLdt));
    2039         return VERR_SELECTOR_NOT_PRESENT;
    2040     }
    2041 
    2042     /* Check if LDT descriptor is not present. */
    2043     if (Desc.Gen.u1Present == 0)
    2044         return VERR_SELECTOR_NOT_PRESENT;
    2045 
    2046     /* Check LDT descriptor type. */
    2047     if (    Desc.Gen.u1DescType == 1
    2048         ||  Desc.Gen.u4Type != X86_SEL_TYPE_SYS_LDT)
    2049         return VERR_INVALID_SELECTOR;
    2050 
    2051     /* LDT descriptor is ok. */
    2052     if (ppvLdt)
    2053     {
    2054         *ppvLdt = (RTGCPTR)X86DESC_BASE(&Desc);
    2055         *pcbLimit = X86DESC_LIMIT_G(&Desc);
    2056     }
    2057     return VINF_SUCCESS;
    2058 }
    2059 
    2060 
    2061 /**
    20622012 * Gets information about a 64-bit selector, SELMR3GetSelectorInfo helper.
    20632013 *
     
    20752025     * Read it from the guest descriptor table.
    20762026     */
     2027/** @todo this is bogus wrt the LDT/GDT limit on long selectors. */
    20772028    X86DESC64   Desc;
    2078     VBOXGDTR    Gdtr;
    20792029    RTGCPTR     GCPtrDesc;
    2080     CPUMGetGuestGDTR(pVCpu, &Gdtr);
    20812030    if (!(Sel & X86_SEL_LDT))
    20822031    {
    20832032        /* GDT */
    2084         if ((unsigned)(Sel & X86_SEL_MASK) + sizeof(X86DESC) - 1 > (unsigned)Gdtr.cbGdt)
     2033        VBOXGDTR Gdtr;
     2034        CPUMGetGuestGDTR(pVCpu, &Gdtr);
     2035        if ((Sel | X86_SEL_RPL_LDT) > Gdtr.cbGdt)
    20852036            return VERR_INVALID_SELECTOR;
    20862037        GCPtrDesc = Gdtr.pGdt + (Sel & X86_SEL_MASK);
     
    20882039    else
    20892040    {
    2090         /*
    2091          * LDT - must locate the LDT first.
    2092          */
    2093         RTSEL SelLdt = CPUMGetGuestLDTR(pVCpu);
    2094         if (    (unsigned)(SelLdt & X86_SEL_MASK) < sizeof(X86DESC) /* the first selector is invalid, right? */ /** @todo r=bird: No, I don't think so */
    2095             ||  (unsigned)(SelLdt & X86_SEL_MASK) + sizeof(X86DESC) - 1 > (unsigned)Gdtr.cbGdt)
     2041        /* LDT */
     2042        uint64_t GCPtrBase;
     2043        uint32_t cbLimit;
     2044        CPUMGetGuestLdtrEx(pVCpu, &GCPtrBase, &cbLimit);
     2045        if ((Sel | X86_SEL_RPL_LDT) > cbLimit)
    20962046            return VERR_INVALID_SELECTOR;
    2097         GCPtrDesc = Gdtr.pGdt + (SelLdt & X86_SEL_MASK);
    2098         int rc = PGMPhysSimpleReadGCPtr(pVCpu, &Desc, GCPtrDesc, sizeof(Desc));
    2099         if (RT_FAILURE(rc))
    2100             return rc;
    2101 
    2102         /* validate the LDT descriptor. */
    2103         if (Desc.Gen.u1Present == 0)
    2104             return VERR_SELECTOR_NOT_PRESENT;
    2105         if (    Desc.Gen.u1DescType == 1
    2106             ||  Desc.Gen.u4Type != AMD64_SEL_TYPE_SYS_LDT)
    2107             return VERR_INVALID_SELECTOR;
    2108 
    2109         uint32_t cbLimit = X86DESC_LIMIT_G(&Desc);
    2110         if ((uint32_t)(Sel & X86_SEL_MASK) + sizeof(X86DESC) - 1 > cbLimit)
    2111             return VERR_INVALID_SELECTOR;
    21122047
    21132048        /* calc the descriptor location. */
    2114         GCPtrDesc = X86DESC64_BASE(&Desc);
    2115         GCPtrDesc += (Sel & X86_SEL_MASK);
     2049        GCPtrDesc = GCPtrBase + (Sel & X86_SEL_MASK);
    21162050    }
    21172051
     
    22552189    X86DESC Desc;
    22562190    if (    !(Sel & X86_SEL_LDT)
    2257         && (    pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS] == (Sel & X86_SEL_MASK)
    2258             ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS] == (Sel & X86_SEL_MASK)
    2259             ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64] == (Sel & X86_SEL_MASK)
    2260             ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS] == (Sel & X86_SEL_MASK)
    2261             ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] == (Sel & X86_SEL_MASK))
     2191        && (    pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]         == (Sel & X86_SEL_RPL_LDT)
     2192            ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]         == (Sel & X86_SEL_RPL_LDT)
     2193            ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64]       == (Sel & X86_SEL_RPL_LDT)
     2194            ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]        == (Sel & X86_SEL_RPL_LDT)
     2195            ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] == (Sel & X86_SEL_RPL_LDT))
    22622196       )
    22632197    {
     
    22802214        pSelInfo->fFlags = DBGFSELINFO_FLAGS_PROT_MODE;
    22812215
    2282         VBOXGDTR    Gdtr;
    22832216        RTGCPTR     GCPtrDesc;
    2284         CPUMGetGuestGDTR(pVCpu, &Gdtr);
    22852217        if (!(Sel & X86_SEL_LDT))
    22862218        {
    22872219            /* GDT */
    2288             if ((unsigned)(Sel & X86_SEL_MASK) + sizeof(X86DESC) - 1 > (unsigned)Gdtr.cbGdt)
     2220            VBOXGDTR Gdtr;
     2221            CPUMGetGuestGDTR(pVCpu, &Gdtr);
     2222            if ((Sel | X86_SEL_RPL_LDT) > Gdtr.cbGdt)
    22892223                return VERR_INVALID_SELECTOR;
    22902224            GCPtrDesc = Gdtr.pGdt + (Sel & X86_SEL_MASK);
     
    22922226        else
    22932227        {
    2294             /*
    2295              * LDT - must locate the LDT first...
    2296              */
    2297             RTSEL SelLdt = CPUMGetGuestLDTR(pVCpu);
    2298             if (    (unsigned)(SelLdt & X86_SEL_MASK) < sizeof(X86DESC) /* the first selector is invalid, right? */ /** @todo r=bird: No, I don't think so */
    2299                 ||  (unsigned)(SelLdt & X86_SEL_MASK) + sizeof(X86DESC) - 1 > (unsigned)Gdtr.cbGdt)
     2228            /* LDT */
     2229            uint64_t GCPtrBase;
     2230            uint32_t cbLimit;
     2231            CPUMGetGuestLdtrEx(pVCpu, &GCPtrBase, &cbLimit);
     2232            if ((Sel | X86_SEL_RPL_LDT) > cbLimit)
    23002233                return VERR_INVALID_SELECTOR;
    2301             GCPtrDesc = Gdtr.pGdt + (SelLdt & X86_SEL_MASK);
    2302             int rc = PGMPhysSimpleReadGCPtr(pVCpu, &Desc, GCPtrDesc, sizeof(Desc));
    2303             if (RT_FAILURE(rc))
    2304                 return rc;
    2305 
    2306             /* validate the LDT descriptor. */
    2307             if (Desc.Gen.u1Present == 0)
    2308                 return VERR_SELECTOR_NOT_PRESENT;
    2309             if (    Desc.Gen.u1DescType == 1
    2310                 ||  Desc.Gen.u4Type != X86_SEL_TYPE_SYS_LDT)
    2311                 return VERR_INVALID_SELECTOR;
    2312 
    2313             uint32_t cbLimit = X86DESC_LIMIT_G(&Desc);
    2314             if ((uint32_t)(Sel & X86_SEL_MASK) + sizeof(X86DESC) - 1 > cbLimit)
    2315                 return VERR_INVALID_SELECTOR;
    23162234
    23172235            /* calc the descriptor location. */
    2318             GCPtrDesc = X86DESC_BASE(&Desc);
    2319             GCPtrDesc += (Sel & X86_SEL_MASK);
     2236            GCPtrDesc = GCPtrBase + (Sel & X86_SEL_MASK);
    23202237        }
    23212238
     
    24162333         */
    24172334        Desc = pVM->selm.s.paGdtR3[Sel >> X86_SEL_SHIFT];
    2418         pSelInfo->fFlags =    pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS] == (Sel & X86_SEL_MASK)
    2419                            || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS] == (Sel & X86_SEL_MASK)
    2420                            || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64] == (Sel & X86_SEL_MASK)
    2421                            || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS] == (Sel & X86_SEL_MASK)
    2422                            || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] == (Sel & X86_SEL_MASK)
     2335        pSelInfo->fFlags =    pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]         == (Sel & X86_SEL_MASK_OFF_RPL)
     2336                           || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]         == (Sel & X86_SEL_MASK_OFF_RPL)
     2337                           || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64]       == (Sel & X86_SEL_MASK_OFF_RPL)
     2338                           || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]        == (Sel & X86_SEL_MASK_OFF_RPL)
     2339                           || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] == (Sel & X86_SEL_MASK_OFF_RPL)
    24232340                         ? DBGFSELINFO_FLAGS_HYPER
    24242341                         : 0;
     
    26662583{
    26672584    /** @todo SMP support! */
    2668     PVMCPU      pVCpu = &pVM->aCpus[0];
    2669 
    2670     RTSEL SelLdt = CPUMGetGuestLDTR(pVCpu);
    2671     if (!(SelLdt & X86_SEL_MASK))
     2585    PVMCPU   pVCpu = &pVM->aCpus[0];
     2586
     2587    uint64_t GCPtrLdt;
     2588    uint32_t cbLdt;
     2589    RTSEL    SelLdt = CPUMGetGuestLdtrEx(pVCpu, &GCPtrLdt, &cbLdt);
     2590    if (!(SelLdt & X86_SEL_MASK_OFF_RPL))
    26722591    {
    26732592        pHlp->pfnPrintf(pHlp, "Guest LDT (Sel=%x): Null-Selector\n", SelLdt);
     
    26752594    }
    26762595
    2677     RTGCPTR     GCPtrLdt;
    2678     unsigned    cbLdt;
    2679     int rc = SELMGetLDTFromSel(pVM, SelLdt, &GCPtrLdt, &cbLdt);
    2680     if (RT_FAILURE(rc))
    2681     {
    2682         pHlp->pfnPrintf(pHlp, "Guest LDT (Sel=%x): rc=%Rrc\n", SelLdt, rc);
    2683         return;
    2684     }
    2685 
    2686     pHlp->pfnPrintf(pHlp, "Guest LDT (Sel=%x GCAddr=%RGv limit=%x):\n", SelLdt, GCPtrLdt, cbLdt);
    2687     unsigned    cLdts  = (cbLdt + 1) >> X86_SEL_SHIFT;
     2596    pHlp->pfnPrintf(pHlp, "Guest LDT (Sel=%x GCAddr=%RX64 limit=%x):\n", SelLdt, GCPtrLdt, cbLdt);
     2597    unsigned cLdts  = (cbLdt + 1) >> X86_SEL_SHIFT;
    26882598    for (unsigned iLdt = 0; iLdt < cLdts; iLdt++, GCPtrLdt += sizeof(X86DESC))
    26892599    {
    26902600        X86DESC LdtE;
    2691         rc = PGMPhysSimpleReadGCPtr(pVCpu, &LdtE, GCPtrLdt, sizeof(LdtE));
     2601        int rc = PGMPhysSimpleReadGCPtr(pVCpu, &LdtE, GCPtrLdt, sizeof(LdtE));
    26922602        if (RT_SUCCESS(rc))
    26932603        {
  • trunk/src/VBox/VMM/VMMRC/SELMRC.cpp

    r42407 r42427  
    9595     */
    9696    RTSEL   Sel = iGDTEntry << X86_SEL_SHIFT;
    97     Assert(   !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS] & ~X86_SEL_MASK)
    98            && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS] & ~X86_SEL_MASK)
    99            && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64] & ~X86_SEL_MASK)
    100            && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS] & ~X86_SEL_MASK)
    101            && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] & ~X86_SEL_MASK));
     97    Assert(   !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]         & ~X86_SEL_MASK_OFF_RPL)
     98           && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]         & ~X86_SEL_MASK_OFF_RPL)
     99           && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64]       & ~X86_SEL_MASK_OFF_RPL)
     100           && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]        & ~X86_SEL_MASK_OFF_RPL)
     101           && !(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] & ~X86_SEL_MASK_OFF_RPL));
    102102    if (    pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]         == Sel
    103103        ||  pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]         == Sel
     
    137137    for (unsigned iSReg = 0; iSReg <= X86_SREG_COUNT; iSReg++)
    138138    {
    139         if (Sel == (paSReg[iSReg].Sel & X86_SEL_MASK_RPL))
     139        if (Sel == (paSReg[iSReg].Sel & X86_SEL_MASK_OFF_RPL))
    140140        {
    141141            if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &paSReg[iSReg]))
     
    200200    for (unsigned iSReg = 0; iSReg <= X86_SREG_COUNT; iSReg++)
    201201    {
    202         if (iGDTEntry == (paSReg[iSReg].Sel & X86_SEL_MASK_RPL))
     202        if (iGDTEntry == (paSReg[iSReg].Sel & X86_SEL_MASK_OFF_RPL))
    203203        {
    204204            if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &paSReg[iSReg]))
Note: See TracChangeset for help on using the changeset viewer.

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