VirtualBox

Changeset 47309 in vbox for trunk/src/recompiler


Ignore:
Timestamp:
Jul 22, 2013 2:42:08 PM (11 years ago)
Author:
vboxsync
Message:

REM: Try set DESC_INTEL_UNUSED where applicable. Fixed values in DR6, mapped DR5 to DR7 and DR4 to DR6.

Location:
trunk/src/recompiler
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/VBoxRecompiler.c

    r46493 r47309  
    8383/** How remR3RunLoggingStep operates. */
    8484#define REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
     85
     86
     87/** Selector flag shift between qemu and VBox.
     88 * VBox shifts the qemu bits to the right. */
     89#define SEL_FLAGS_SHIFT     (8)
     90/** Mask applied to the shifted qemu selector flags to get the attributes VBox
     91 * (VT-x) needs. */
     92#define SEL_FLAGS_SMASK     UINT32_C(0x1F0FF)
    8593
    8694
     
    14031411        Ctx.tr.u64Base     = env->tr.base;
    14041412        Ctx.tr.u32Limit    = env->tr.limit;
    1405         Ctx.tr.Attr.u      = (env->tr.flags >> 8) & 0xF0FF;
     1413        Ctx.tr.Attr.u      = (env->tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    14061414
    14071415        Ctx.ldtr.Sel       = env->ldt.selector;
     
    14101418        Ctx.ldtr.u64Base   = env->ldt.base;
    14111419        Ctx.ldtr.u32Limit  = env->ldt.limit;
    1412         Ctx.ldtr.Attr.u    = (env->ldt.flags >> 8) & 0xF0FF;
     1420        Ctx.ldtr.Attr.u    = (env->ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    14131421
    14141422        Ctx.idtr.cbIdt     = env->idt.limit;
     
    14281436        Ctx.cs.u64Base     = env->segs[R_CS].base;
    14291437        Ctx.cs.u32Limit    = env->segs[R_CS].limit;
    1430         Ctx.cs.Attr.u      = (env->segs[R_CS].flags >> 8) & 0xF0FF;
     1438        Ctx.cs.Attr.u      = (env->segs[R_CS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    14311439
    14321440        Ctx.ds.Sel         = env->segs[R_DS].selector;
     
    14351443        Ctx.ds.u64Base     = env->segs[R_DS].base;
    14361444        Ctx.ds.u32Limit    = env->segs[R_DS].limit;
    1437         Ctx.ds.Attr.u      = (env->segs[R_DS].flags >> 8) & 0xF0FF;
     1445        Ctx.ds.Attr.u      = (env->segs[R_DS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    14381446
    14391447        Ctx.es.Sel         = env->segs[R_ES].selector;
     
    14421450        Ctx.es.u64Base     = env->segs[R_ES].base;
    14431451        Ctx.es.u32Limit    = env->segs[R_ES].limit;
    1444         Ctx.es.Attr.u      = (env->segs[R_ES].flags >> 8) & 0xF0FF;
     1452        Ctx.es.Attr.u      = (env->segs[R_ES].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    14451453
    14461454        Ctx.fs.Sel         = env->segs[R_FS].selector;
     
    14491457        Ctx.fs.u64Base     = env->segs[R_FS].base;
    14501458        Ctx.fs.u32Limit    = env->segs[R_FS].limit;
    1451         Ctx.fs.Attr.u      = (env->segs[R_FS].flags >> 8) & 0xF0FF;
     1459        Ctx.fs.Attr.u      = (env->segs[R_FS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    14521460
    14531461        Ctx.gs.Sel         = env->segs[R_GS].selector;
     
    14561464        Ctx.gs.u64Base     = env->segs[R_GS].base;
    14571465        Ctx.gs.u32Limit    = env->segs[R_GS].limit;
    1458         Ctx.gs.Attr.u      = (env->segs[R_GS].flags >> 8) & 0xF0FF;
     1466        Ctx.gs.Attr.u      = (env->segs[R_GS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    14591467
    14601468        Ctx.ss.Sel         = env->segs[R_SS].selector;
     
    14631471        Ctx.ss.u64Base     = env->segs[R_SS].base;
    14641472        Ctx.ss.u32Limit    = env->segs[R_SS].limit;
    1465         Ctx.ss.Attr.u      = (env->segs[R_SS].flags >> 8) & 0xF0FF;
     1473        Ctx.ss.Attr.u      = (env->segs[R_SS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    14661474
    14671475        Ctx.msrEFER        = env->efer;
     
    23172325                pVM->rem.s.Env.ldt.base        = pCtx->ldtr.u64Base;
    23182326                pVM->rem.s.Env.ldt.limit       = pCtx->ldtr.u32Limit;
    2319                 pVM->rem.s.Env.ldt.flags       = (pCtx->ldtr.Attr.u << 8) & 0xFFFFFF;
     2327                pVM->rem.s.Env.ldt.flags       = (pCtx->ldtr.Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT;
    23202328            }
    23212329            else
     
    23502358    pVM->rem.s.Env.tr.base        = pCtx->tr.u64Base;
    23512359    pVM->rem.s.Env.tr.limit       = pCtx->tr.u32Limit;
    2352     pVM->rem.s.Env.tr.flags       = (pCtx->tr.Attr.u << 8) & 0xFFFFFF;
    2353     /* Note! do_interrupt will fault if the busy flag is still set... */
     2360    pVM->rem.s.Env.tr.flags       = (pCtx->tr.Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT;
     2361    /* Note! do_interrupt will fault if the busy flag is still set... */ /** @todo so fix do_interrupt then! */
    23542362    pVM->rem.s.Env.tr.flags      &= ~DESC_TSS_BUSY_MASK;
    23552363
     
    23752383                                       (a_pVBoxSReg)->u64Base, \
    23762384                                       (a_pVBoxSReg)->u32Limit, \
    2377                                        ((a_pVBoxSReg)->Attr.u << 8) & 0xFFFFFF); \
     2385                                       ((a_pVBoxSReg)->Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT); \
    23782386                (a_pRemSReg)->fVBoxFlags = (a_pVBoxSReg)->fFlags; \
    23792387            } \
     
    25742582                pCtx->a_sreg.u64Base  = pVM->rem.s.Env.segs[R_##a_SREG].base; \
    25752583                pCtx->a_sreg.u32Limit = pVM->rem.s.Env.segs[R_##a_SREG].limit; \
    2576                 /* Note! QEmu saves the 2nd dword of the descriptor; we should store the attribute word only! */ \
    2577                 pCtx->a_sreg.Attr.u   = (pVM->rem.s.Env.segs[R_##a_SREG].flags >> 8) & 0xF0FF; \
     2584                /* Note! QEmu saves the 2nd dword of the descriptor; we (VT-x/AMD-V) keep only the attributes! */ \
     2585                pCtx->a_sreg.Attr.u   = (pVM->rem.s.Env.segs[R_##a_SREG].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; \
    25782586            } \
    25792587            else \
     
    26372645        ||  pCtx->ldtr.u64Base  != pVM->rem.s.Env.ldt.base
    26382646        ||  pCtx->ldtr.u32Limit != pVM->rem.s.Env.ldt.limit
    2639         ||  pCtx->ldtr.Attr.u   != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF)
     2647        ||  pCtx->ldtr.Attr.u   != ((pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK)
    26402648        ||  !(pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID)
    26412649       )
     
    26462654        pCtx->ldtr.u64Base  = pVM->rem.s.Env.ldt.base;
    26472655        pCtx->ldtr.u32Limit = pVM->rem.s.Env.ldt.limit;
    2648         pCtx->ldtr.Attr.u   = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;
     2656        pCtx->ldtr.Attr.u   = (pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    26492657        STAM_COUNTER_INC(&gStatREMLDTRChange);
    26502658#ifdef VBOX_WITH_RAW_MODE
     
    26582666        ||  pCtx->tr.u64Base  != pVM->rem.s.Env.tr.base
    26592667        ||  pCtx->tr.u32Limit != pVM->rem.s.Env.tr.limit
    2660             /* Qemu and AMD/Intel have different ideas about the busy flag ... */
    2661         ||  pCtx->tr.Attr.u   != (  (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF
    2662                                   ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8
     2668            /* Qemu and AMD/Intel have different ideas about the busy flag ... */ /** @todo just fix qemu! */
     2669        ||  pCtx->tr.Attr.u   != (  (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE)
     2670                                  ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT
    26632671                                  : 0)
    26642672        ||  !(pCtx->tr.fFlags & CPUMSELREG_FLAGS_VALID)
     
    26682676             pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
    26692677             pVM->rem.s.Env.tr.selector, (uint64_t)pVM->rem.s.Env.tr.base, pVM->rem.s.Env.tr.limit,
    2670              (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8 : 0));
     2678             (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE)
     2679             ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT : 0));
    26712680        pCtx->tr.Sel        = pVM->rem.s.Env.tr.selector;
    26722681        pCtx->tr.ValidSel   = pVM->rem.s.Env.tr.selector;
     
    26742683        pCtx->tr.u64Base    = pVM->rem.s.Env.tr.base;
    26752684        pCtx->tr.u32Limit   = pVM->rem.s.Env.tr.limit;
    2676         pCtx->tr.Attr.u     = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;
    2677         if (pCtx->tr.Attr.u)
    2678             pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
     2685        pCtx->tr.Attr.u     = (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
     2686        if (pCtx->tr.Attr.u & ~DESC_INTEL_UNUSABLE)
     2687            pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> SEL_FLAGS_SHIFT;
    26792688        STAM_COUNTER_INC(&gStatREMTRChange);
    26802689#ifdef VBOX_WITH_RAW_MODE
     
    28772886        ||  pCtx->ldtr.u64Base  != pVM->rem.s.Env.ldt.base
    28782887        ||  pCtx->ldtr.u32Limit != pVM->rem.s.Env.ldt.limit
    2879         ||  pCtx->ldtr.Attr.u   != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF)
     2888        ||  pCtx->ldtr.Attr.u   != ((pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK)
    28802889        ||  !(pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID)
    28812890       )
     
    28862895        pCtx->ldtr.u64Base  = pVM->rem.s.Env.ldt.base;
    28872896        pCtx->ldtr.u32Limit = pVM->rem.s.Env.ldt.limit;
    2888         pCtx->ldtr.Attr.u   = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;
     2897        pCtx->ldtr.Attr.u   = (pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
    28892898        STAM_COUNTER_INC(&gStatREMLDTRChange);
    28902899#ifdef VBOX_WITH_RAW_MODE
     
    28992908        ||  pCtx->tr.u32Limit != pVM->rem.s.Env.tr.limit
    29002909            /* Qemu and AMD/Intel have different ideas about the busy flag ... */
    2901         ||  pCtx->tr.Attr.u   != (  (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF
    2902                                   ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8
     2910        ||  pCtx->tr.Attr.u   != (  (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE)
     2911                                  ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT
    29032912                                  : 0)
    29042913        ||  !(pCtx->tr.fFlags & CPUMSELREG_FLAGS_VALID)
     
    29082917             pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
    29092918             pVM->rem.s.Env.tr.selector, (uint64_t)pVM->rem.s.Env.tr.base, pVM->rem.s.Env.tr.limit,
    2910              (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8 : 0));
     2919             (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE)
     2920             ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT : 0));
    29112921        pCtx->tr.Sel        = pVM->rem.s.Env.tr.selector;
    29122922        pCtx->tr.ValidSel   = pVM->rem.s.Env.tr.selector;
     
    29142924        pCtx->tr.u64Base    = pVM->rem.s.Env.tr.base;
    29152925        pCtx->tr.u32Limit   = pVM->rem.s.Env.tr.limit;
    2916         pCtx->tr.Attr.u     = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;
    2917         if (pCtx->tr.Attr.u)
    2918             pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
     2926        pCtx->tr.Attr.u     = (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
     2927        if (pCtx->tr.Attr.u & ~DESC_INTEL_UNUSABLE)
     2928            pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> SEL_FLAGS_SHIFT;
    29192929        STAM_COUNTER_INC(&gStatREMTRChange);
    29202930#ifdef VBOX_WITH_RAW_MODE
  • trunk/src/recompiler/target-i386/cpu.h

    r43394 r47309  
    116116
    117117#define DESC_TSS_BUSY_MASK (1 << 9)
     118#ifdef VBOX
     119# define DESC_INTEL_UNUSABLE    RT_BIT_32(16+8) /**< Internal VT-x bit for NULL sectors. */
     120#endif
    118121
    119122/* eflags masks */
     
    949952    if (flags & DESC_P_MASK)
    950953        flags |= DESC_A_MASK;           /* Make sure the A bit is set to avoid trouble. */
     954    if (selector < 4U && (env->hflags & HF_CS64_MASK))
     955        flags |= DESC_INTEL_UNUSABLE;
     956    else
     957        flags &= ~DESC_INTEL_UNUSABLE;
    951958    sc->flags = flags;
    952959    sc->newselector = 0;
  • trunk/src/recompiler/target-i386/op_helper.c

    r45494 r47309  
    274274    sc->flags = e2;
    275275#ifdef VBOX
     276    sc->flags &= ~DESC_INTEL_UNUSABLE;
    276277    sc->newselector = 0;
    277278    sc->fVBoxFlags  = CPUMSELREG_FLAGS_VALID;
     
    624625    env->ldt.flags = 0;
    625626#ifdef VBOX
     627    env->ldt.flags = DESC_INTEL_UNUSABLE;
    626628    env->ldt.fVBoxFlags  = CPUMSELREG_FLAGS_VALID;
    627629    env->ldt.newselector = 0;
     
    13261328    if (new_stack) {
    13271329        ss = 0 | dpl;
     1330#ifndef VBOX
    13281331        cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
     1332#else
     1333        cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, dpl << DESC_DPL_SHIFT);
     1334#endif
    13291335    }
    13301336    ESP = esp;
     
    25032509        env->ldt.limit = 0;
    25042510#ifdef VBOX
     2511        env->ldt.flags = DESC_INTEL_UNUSABLE;
    25052512        env->ldt.fVBoxFlags = CPUMSELREG_FLAGS_VALID;
    25062513        env->ldt.newselector = 0;
     
    25692576        env->tr.flags = 0;
    25702577#ifdef VBOX
     2578        env->tr.flags = DESC_INTEL_UNUSABLE;
    25712579        env->tr.fVBoxFlags  = CPUMSELREG_FLAGS_VALID;
    25722580        env->tr.newselector = 0;
     
    26452653    if ((selector & 0xfffc) == 0) {
    26462654        /* null selector case */
     2655#ifndef VBOX
    26472656        if (seg_reg == R_SS
    26482657#ifdef TARGET_X86_64
     
    26522661            raise_exception_err(EXCP0D_GPF, 0);
    26532662        cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
     2663#else
     2664        if (seg_reg == R_SS) {
     2665            if (!(env->hflags & HF_CS64_MASK) || cpl == 3)
     2666                raise_exception_err(EXCP0D_GPF, 0);
     2667            e2 = (cpl << DESC_DPL_SHIFT) | DESC_INTEL_UNUSABLE;
     2668        } else {
     2669            e2 = DESC_INTEL_UNUSABLE;
     2670        }
     2671        cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, e2);
     2672#endif
    26542673    } else {
    26552674
     
    33213340#endif
    33223341            {
     3342#if defined(VBOX) && defined(DEBUG)
     3343                Log(("NULL ss, rpl=%d\n", rpl));
     3344#endif
    33233345                raise_exception_err(EXCP0D_GPF, 0);
    33243346            }
    33253347        } else {
    33263348            if ((new_ss & 3) != rpl)
     3349            {
     3350#if defined(VBOX) && defined(DEBUG)
     3351                Log(("new_ss=%x != rpl=%d\n", new_ss, rpl));
     3352#endif
    33273353                raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
     3354            }
    33283355            if (load_segment(&ss_e1, &ss_e2, new_ss) != 0)
     3356            {
     3357#if defined(VBOX) && defined(DEBUG)
     3358                Log(("new_ss=%x load error\n", new_ss));
     3359#endif
    33293360                raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
     3361            }
    33303362            if (!(ss_e2 & DESC_S_MASK) ||
    33313363                (ss_e2 & DESC_CS_MASK) ||
    33323364                !(ss_e2 & DESC_W_MASK))
     3365            {
     3366#if defined(VBOX) && defined(DEBUG)
     3367                Log(("new_ss=%x ss_e2=%#x bad type\n", new_ss, ss_e2));
     3368#endif
    33333369                raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
     3370            }
    33343371            dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
    33353372            if (dpl != rpl)
     3373            {
     3374#if defined(VBOX) && defined(DEBUG)
     3375                Log(("SS.dpl=%u  !=  rpl=%u\n", dpl, rpl));
     3376#endif
    33363377                raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
     3378            }
    33373379            if (!(ss_e2 & DESC_P_MASK))
     3380            {
     3381#if defined(VBOX) && defined(DEBUG)
     3382                Log(("new_ss=%#x #NP\n", new_ss));
     3383#endif
    33383384                raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);
     3385            }
    33393386#ifdef VBOX
    33403387            if (!(e2 & DESC_A_MASK))
     
    34193466
    34203467#ifdef VBOX
     3468    Log(("iret (shift=%d new_eip=%#x)\n", shift, next_eip));
    34213469    e1 = e2 = 0; /** @todo Why do we do this? */
    34223470    remR3TrapClear(env->pVM);
     
    34273475#ifdef TARGET_X86_64
    34283476        if (env->hflags & HF_LMA_MASK)
     3477        {
     3478#if defined(VBOX) && defined(DEBUG)
     3479            Log(("eflags.NT=1 on iret in long mode\n"));
     3480#endif
    34293481            raise_exception_err(EXCP0D_GPF, 0);
     3482        }
    34303483#endif
    34313484        tss_selector = lduw_kernel(env->tr.base + 0);
     
    35973650        env->dr[reg] = t0;
    35983651        hw_breakpoint_insert(env, reg);
     3652# ifndef VBOX
    35993653    } else if (reg == 7) {
     3654# else
     3655    } else if (reg == 7 || reg == 5) {
     3656# endif
    36003657        for (i = 0; i < 4; i++)
    36013658            hw_breakpoint_remove(env, i);
     
    36043661            hw_breakpoint_insert(env, i);
    36053662    } else
     3663# ifndef VBOX
    36063664        env->dr[reg] = t0;
     3665# else
     3666        env->dr[6] = (t0 & ~RT_BIT_32(12)) | UINT32_C(0xffff0ff0); /* 4 is an alias for 6. */
     3667# endif
    36073668}
    36083669#endif
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