VirtualBox

Changeset 48450 in vbox


Ignore:
Timestamp:
Sep 12, 2013 3:00:15 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
88906
Message:

Corrected hmR3IsCodeSelectorOkForVmx, hmR3IsStackSelectorOkForVmx and hmR3IsDataSelectorOkForVmx as they wasn't taking the unused bit into account and was mixing VT-x requirements with x86/AMD64 CPU requirements.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/HM.cpp

    r48433 r48450  
    22542254 *        false.
    22552255 * @param   pSel        Pointer to the selector to check (CS).
    2256  *          uStackDpl   The DPL of the stack segment.
     2256 *          uStackDpl   The CPL, aka the DPL of the stack segment.
    22572257 */
    22582258static bool hmR3IsCodeSelectorOkForVmx(PCPUMSELREG pSel, unsigned uStackDpl)
    22592259{
    2260     bool    rc = false;
    2261 
    2262     do
    2263     {
    2264         /* Segment must be accessed. */
    2265         if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED))
    2266             break;
    2267         /* Segment must be a code segment. */
    2268         if (!(pSel->Attr.u & X86_SEL_TYPE_CODE))
    2269             break;
    2270         /* The S bit must be set. */
    2271         if (!pSel->Attr.n.u1DescType)
    2272             break;
    2273         if (pSel->Attr.n.u4Type & X86_SEL_TYPE_CONF)
    2274         {
    2275             /* For conforming segments, CS.DPL must be <= SS.DPL. */
    2276             if (pSel->Attr.n.u2Dpl > uStackDpl)
    2277                 break;
    2278         }
    2279         else
    2280         {
    2281             /* For non-conforming segments, CS.DPL must equal SS.DPL. */
    2282             if (pSel->Attr.n.u2Dpl != uStackDpl)
    2283                 break;
    2284         }
    2285         /* Segment must be present. */
    2286         if (!pSel->Attr.n.u1Present)
    2287             break;
    2288         /* G bit must be set if any high limit bits are set. */
    2289         if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity)
    2290             break;
    2291         /* G bit must be clear if any low limit bits are clear. */
    2292         if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity)
    2293             break;
    2294 
    2295         rc = true;
    2296     } while (0);
    2297     return rc;
     2260    /*
     2261     * Segment must be an accessed code segment, it must be present and it must
     2262     * be usable.
     2263     * Note! These are all standard requirements and if CS holds anything else
     2264     *       we've got buggy code somewhere!
     2265     */
     2266    AssertCompile(X86DESCATTR_TYPE == 0xf);
     2267    AssertMsgReturn(   (pSel->Attr.u & (X86_SEL_TYPE_ACCESSED | X86_SEL_TYPE_CODE | X86DESCATTR_DT | X86DESCATTR_P | X86DESCATTR_UNUSABLE))
     2268                    ==                 (X86_SEL_TYPE_ACCESSED | X86_SEL_TYPE_CODE | X86DESCATTR_DT | X86DESCATTR_P),
     2269                    ("%#x\n", pSel->Attr.u),
     2270                    false);
     2271
     2272    /* For conforming segments, CS.DPL must be <= SS.DPL, while CS.DPL
     2273       must equal SS.DPL for non-confroming segments.
     2274       Note! This is also a hard requirement like above. */
     2275    AssertMsgReturn(  pSel->Attr.n.u4Type & X86_SEL_TYPE_CONF
     2276                    ? pSel->Attr.n.u2Dpl <= uStackDpl
     2277                    : pSel->Attr.n.u2Dpl == uStackDpl,
     2278                    ("u4Type=%#x u2Dpl=%u uStackDpl=%u\n", pSel->Attr.n.u4Type, pSel->Attr.n.u2Dpl, uStackDpl),
     2279                    false);
     2280
     2281    /*
     2282     * The following two requirements are VT-x specific:
     2283     *  - G bit must be set if any high limit bits are set.
     2284     *  - G bit must be clear if any low limit bits are clear.
     2285     */
     2286    if (   ((pSel->u32Limit & 0xfff00000) == 0x00000000 ||  pSel->Attr.n.u1Granularity)
     2287        && ((pSel->u32Limit & 0x00000fff) == 0x00000fff || !pSel->Attr.n.u1Granularity) )
     2288        return true;
     2289    return false;
    22982290}
    22992291
     
    23112303static bool hmR3IsDataSelectorOkForVmx(PCPUMSELREG pSel)
    23122304{
    2313     bool    rc = false;
    2314 
    2315     /* If attributes are all zero, consider the segment unusable and therefore OK.
    2316      * This logic must be in sync with HMVMXR0.cpp!
    2317      */
    2318     if (!pSel->Attr.u)
     2305    /*
     2306     * Unusable segments are OK.  These days they should be marked as such, as
     2307     * but as an alternative we for old saved states and AMD<->VT-x migration
     2308     * we also treat segments with all the attributes cleared as unusable.
     2309     */
     2310    if (pSel->Attr.n.u1Unusable || !pSel->Attr.u)
    23192311        return true;
    23202312
    2321     do
    2322     {
    2323         /* Segment must be accessed. */
    2324         if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED))
    2325             break;
     2313    /** @todo tighten these checks. Will require CPUM load adjusting. */
     2314
     2315    /* Segment must be accessed. */
     2316    if (pSel->Attr.u & X86_SEL_TYPE_ACCESSED)
     2317    {
    23262318        /* Code segments must also be readable. */
    2327         if (pSel->Attr.u & X86_SEL_TYPE_CODE && !(pSel->Attr.u & X86_SEL_TYPE_READ))
    2328             break;
    2329         /* The S bit must be set. */
    2330         if (!pSel->Attr.n.u1DescType)
    2331             break;
    2332         /* Except for conforming segments, DPL >= RPL. */
    2333         if (pSel->Attr.n.u4Type <= X86_SEL_TYPE_ER_ACC && pSel->Attr.n.u2Dpl < (pSel->Sel & X86_SEL_RPL))
    2334             break;
    2335         /* Segment must be present. */
    2336         if (!pSel->Attr.n.u1Present)
    2337             break;
    2338         /* G bit must be set if any high limit bits are set. */
    2339         if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity)
    2340             break;
    2341         /* G bit must be clear if any low limit bits are clear. */
    2342         if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity)
    2343             break;
    2344 
    2345         rc = true;
    2346     } while (0);
    2347     return rc;
     2319        if (  !(pSel->Attr.u & X86_SEL_TYPE_CODE)
     2320            || (pSel->Attr.u & X86_SEL_TYPE_READ))
     2321        {
     2322            /* The S bit must be set. */
     2323            if (pSel->Attr.n.u1DescType)
     2324            {
     2325                /* Except for conforming segments, DPL >= RPL. */
     2326                if (   pSel->Attr.n.u2Dpl  >= (pSel->Sel & X86_SEL_RPL)
     2327                    || pSel->Attr.n.u4Type >= X86_SEL_TYPE_ER_ACC)
     2328                {
     2329                    /* Segment must be present. */
     2330                    if (pSel->Attr.n.u1Present)
     2331                    {
     2332                        /*
     2333                         * The following two requirements are VT-x specific:
     2334                         *  - G bit must be set if any high limit bits are set.
     2335                         *  - G bit must be clear if any low limit bits are clear.
     2336                         */
     2337                        if (   ((pSel->u32Limit & 0xfff00000) == 0x00000000 ||  pSel->Attr.n.u1Granularity)
     2338                            && ((pSel->u32Limit & 0x00000fff) == 0x00000fff || !pSel->Attr.n.u1Granularity) )
     2339                            return true;
     2340                    }
     2341                }
     2342            }
     2343        }
     2344    }
     2345
     2346    return false;
    23482347}
    23492348
     
    23592358static bool hmR3IsStackSelectorOkForVmx(PCPUMSELREG pSel)
    23602359{
    2361     bool    rc = false;
    2362 
    2363     /* If attributes are all zero, consider the segment unusable and therefore OK.
    2364      * This logic must be in sync with HMVMXR0.cpp!
    2365      */
    2366     if (!pSel->Attr.u)
     2360    /*
     2361     * Unusable segments are OK.  These days they should be marked as such, as
     2362     * but as an alternative we for old saved states and AMD<->VT-x migration
     2363     * we also treat segments with all the attributes cleared as unusable.
     2364     */
     2365    /** @todo r=bird: actually all zeros isn't gonna cut it... SS.DPL == CPL. */
     2366    if (pSel->Attr.n.u1Unusable || !pSel->Attr.u)
    23672367        return true;
    23682368
    2369     do
    2370     {
    2371         /* Segment must be accessed. */
    2372         if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED))
    2373             break;
    2374         /* Segment must be writable. */
    2375         if (!(pSel->Attr.u & X86_SEL_TYPE_WRITE))
    2376             break;
    2377         /* Segment must not be a code segment. */
    2378         if (pSel->Attr.u & X86_SEL_TYPE_CODE)
    2379             break;
    2380         /* The S bit must be set. */
    2381         if (!pSel->Attr.n.u1DescType)
    2382             break;
    2383         /* DPL must equal RPL. */
    2384         if (pSel->Attr.n.u2Dpl != (pSel->Sel & X86_SEL_RPL))
    2385             break;
    2386         /* Segment must be present. */
    2387         if (!pSel->Attr.n.u1Present)
    2388             break;
    2389         /* G bit must be set if any high limit bits are set. */
    2390         if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity)
    2391             break;
    2392         /* G bit must be clear if any low limit bits are clear. */
    2393         if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity)
    2394             break;
    2395 
    2396         rc = true;
    2397     } while (0);
    2398     return rc;
     2369    /*
     2370     * Segment must be an accessed writable segment, it must be present.
     2371     * Note! These are all standard requirements and if SS holds anything else
     2372     *       we've got buggy code somewhere!
     2373     */
     2374    AssertCompile(X86DESCATTR_TYPE == 0xf);
     2375    AssertMsgReturn(   (pSel->Attr.u & (X86_SEL_TYPE_ACCESSED | X86_SEL_TYPE_WRITE | X86DESCATTR_DT | X86DESCATTR_P | X86_SEL_TYPE_CODE))
     2376                    ==                 (X86_SEL_TYPE_ACCESSED | X86_SEL_TYPE_WRITE | X86DESCATTR_DT | X86DESCATTR_P),
     2377                    ("%#x\n", pSel->Attr.u),
     2378                    false);
     2379
     2380    /* DPL must equal RPL.
     2381       Note! This is also a hard requirement like above. */
     2382    AssertMsgReturn(pSel->Attr.n.u2Dpl == (pSel->Sel & X86_SEL_RPL),
     2383                    ("u2Dpl=%u Sel=%#x\n", pSel->Attr.n.u2Dpl, pSel->Sel),
     2384                    false);
     2385
     2386    /*
     2387     * The following two requirements are VT-x specific:
     2388     *  - G bit must be set if any high limit bits are set.
     2389     *  - G bit must be clear if any low limit bits are clear.
     2390     */
     2391    if (   ((pSel->u32Limit & 0xfff00000) == 0x00000000 ||  pSel->Attr.n.u1Granularity)
     2392        && ((pSel->u32Limit & 0x00000fff) == 0x00000fff || !pSel->Attr.n.u1Granularity) )
     2393        return true;
     2394    return false;
    23992395}
    24002396
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