VirtualBox

Changeset 45821 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Apr 29, 2013 3:34:47 PM (12 years ago)
Author:
vboxsync
Message:

HM/VMX: More accurate entry checks.

File:
1 edited

Legend:

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

    r45804 r45821  
    22882288
    22892289/**
     2290 * Checks if a code selector (CS) is suitable for execution
     2291 * within VMX when unrestricted execution isn't available.
     2292 *
     2293 * @returns true if selector is suitable for VMX, otherwise
     2294 *        false.
     2295 * @param   pSel        Pointer to the selector to check (CS).
     2296 *          uStackDpl   The DPL of the stack segment.
     2297 */
     2298static bool hmR3IsCodeSelectorOkForVmx(PCPUMSELREG pSel, unsigned uStackDpl)
     2299{
     2300    bool    rc = false;
     2301
     2302    do
     2303    {
     2304        /* Segment must be accessed. */
     2305        if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED))
     2306            break;
     2307        /* Segment must be a code segment. */
     2308        if (!(pSel->Attr.u & X86_SEL_TYPE_CODE))
     2309            break;
     2310        /* The S bit must be set. */
     2311        if (!pSel->Attr.n.u1DescType)
     2312            break;
     2313        if (pSel->Attr.n.u4Type & X86_SEL_TYPE_CONF)
     2314        {
     2315            /* For conforming segments, CS.DPL must be <= SS.DPL. */
     2316            if (pSel->Attr.n.u2Dpl > uStackDpl)
     2317                break;
     2318        }
     2319        else
     2320        {
     2321            /* For non-conforming segments, CS.DPL must equal SS.DPL. */
     2322            if (pSel->Attr.n.u2Dpl != uStackDpl)
     2323                break;
     2324        }
     2325        /* Segment must be present. */
     2326        if (!pSel->Attr.n.u1Present)
     2327            break;
     2328        /* G bit must be set if any high limit bits are set. */
     2329        if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity)
     2330            break;
     2331        /* G bit must be clear if any low limit bits are clear. */
     2332        if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity)
     2333            break;
     2334
     2335        rc = true;
     2336    } while (0);
     2337    return rc;
     2338}
     2339
     2340
     2341/**
     2342 * Checks if a data selector (DS/ES/FS/GS) is suitable for
     2343 * execution within VMX when unrestricted execution isn't
     2344 * available.
     2345 *
     2346 * @returns true if selector is suitable for VMX, otherwise
     2347 *        false.
     2348 * @param   pSel        Pointer to the selector to check
     2349 *                      (DS/ES/FS/GS).
     2350 */
     2351static bool hmR3IsDataSelectorOkForVmx(PCPUMSELREG pSel)
     2352{
     2353    bool    rc = false;
     2354
     2355    /* If attributes are all zero, consider the segment unusable and therefore OK.
     2356     * This logic must be in sync with HMVMXR0.cpp!
     2357     */
     2358    if (!pSel->Attr.u)
     2359        return true;
     2360   
     2361    do
     2362    {
     2363        /* Segment must be accessed. */
     2364        if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED))
     2365            break;
     2366        /* Code segments must also be readable. */
     2367        if (pSel->Attr.u & X86_SEL_TYPE_CODE && !(pSel->Attr.u & X86_SEL_TYPE_READ))
     2368            break;
     2369        /* The S bit must be set. */
     2370        if (!pSel->Attr.n.u1DescType)
     2371            break;
     2372        /* Except for conforming segments, DPL >= RPL. */
     2373        if (pSel->Attr.n.u4Type <= X86_SEL_TYPE_ER_ACC && pSel->Attr.n.u2Dpl < (pSel->Sel & X86_SEL_RPL))
     2374            break;
     2375        /* Segment must be present. */
     2376        if (!pSel->Attr.n.u1Present)
     2377            break;
     2378        /* G bit must be set if any high limit bits are set. */
     2379        if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity)
     2380            break;
     2381        /* G bit must be clear if any low limit bits are clear. */
     2382        if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity)
     2383            break;
     2384
     2385        rc = true;
     2386    } while (0);
     2387    return rc;
     2388}
     2389
     2390
     2391/**
     2392 * Checks if the stack selector (SS) is suitable for execution
     2393 * within VMX when unrestricted execution isn't available.
     2394 *
     2395 * @returns true if selector is suitable for VMX, otherwise
     2396 *        false.
     2397 * @param   pSel        Pointer to the selector to check (SS).
     2398 */
     2399static bool hmR3IsStackSelectorOkForVmx(PCPUMSELREG pSel)
     2400{
     2401    bool    rc = false;
     2402
     2403    /* If attributes are all zero, consider the segment unusable and therefore OK.
     2404     * This logic must be in sync with HMVMXR0.cpp!
     2405     */
     2406    if (!pSel->Attr.u)
     2407        return true;
     2408   
     2409    do
     2410    {
     2411        /* Segment must be accessed. */
     2412        if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED))
     2413            break;
     2414        /* Segment must be writable. */
     2415        if (!(pSel->Attr.u & X86_SEL_TYPE_WRITE))
     2416            break;
     2417        /* Segment must not be a code segment. */
     2418        if (pSel->Attr.u & X86_SEL_TYPE_CODE)
     2419            break;
     2420        /* The S bit must be set. */
     2421        if (!pSel->Attr.n.u1DescType)
     2422            break;
     2423        /* DPL must equal RPL. */
     2424        if (pSel->Attr.n.u2Dpl != (pSel->Sel & X86_SEL_RPL))
     2425            break;
     2426        /* Segment must be present. */
     2427        if (!pSel->Attr.n.u1Present)
     2428            break;
     2429        /* G bit must be set if any high limit bits are set. */
     2430        if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity)
     2431            break;
     2432        /* G bit must be clear if any low limit bits are clear. */
     2433        if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity)
     2434            break;
     2435
     2436        rc = true;
     2437    } while (0);
     2438    return rc;
     2439}
     2440
     2441
     2442/**
    22902443 * Force execution of the current IO code in the recompiler.
    22912444 *
     
    23942547#endif
    23952548                {
     2549                    //@todo: If guest is in V86 mode, these checks should be different!
     2550#if VBOX_WITH_OLD_VTX_CODE
    23962551                    if (   (pCtx->cs.Sel & X86_SEL_RPL)
    23972552                        || (pCtx->ds.Sel & X86_SEL_RPL)
     
    24002555                        || (pCtx->gs.Sel & X86_SEL_RPL)
    24012556                        || (pCtx->ss.Sel & X86_SEL_RPL))
     2557#else
     2558                    if (   ((pCtx->cs.Sel & X86_SEL_RPL) != (pCtx->ss.Sel & X86_SEL_RPL))
     2559                        || !hmR3IsCodeSelectorOkForVmx(&pCtx->cs, pCtx->ss.Attr.n.u2Dpl)
     2560                        || !hmR3IsDataSelectorOkForVmx(&pCtx->ds)
     2561                        || !hmR3IsDataSelectorOkForVmx(&pCtx->es)
     2562                        || !hmR3IsDataSelectorOkForVmx(&pCtx->fs)
     2563                        || !hmR3IsDataSelectorOkForVmx(&pCtx->gs)
     2564                        || !hmR3IsStackSelectorOkForVmx(&pCtx->ss))
     2565#endif
    24022566                    {
    24032567                        return false;
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