VirtualBox

Ignore:
Timestamp:
Jun 24, 2012 3:44:03 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
78759
Message:

CPUM: Combined the visible and hidden selector register data into one structure. Preparing for lazily resolving+caching of hidden registers in raw-mode.

File:
1 edited

Legend:

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

    r41675 r41906  
    14411441        Ctx.cr4            = env->cr[4];
    14421442
    1443         Ctx.tr             = env->tr.selector;
    1444         Ctx.trHid.u64Base  = env->tr.base;
    1445         Ctx.trHid.u32Limit = env->tr.limit;
    1446         Ctx.trHid.Attr.u   = (env->tr.flags >> 8) & 0xF0FF;
    1447 
    1448         Ctx.ldtr              = env->ldt.selector;
    1449         Ctx.ldtrHid.u64Base   = env->ldt.base;
    1450         Ctx.ldtrHid.u32Limit  = env->ldt.limit;
    1451         Ctx.ldtrHid.Attr.u    = (env->ldt.flags >> 8) & 0xF0FF;
     1443        Ctx.tr.Sel         = env->tr.selector;
     1444        Ctx.tr.ValidSel    = env->tr.selector;
     1445        Ctx.tr.fFlags      = CPUMSELREG_FLAGS_VALID;
     1446        Ctx.tr.u64Base     = env->tr.base;
     1447        Ctx.tr.u32Limit    = env->tr.limit;
     1448        Ctx.tr.Attr.u      = (env->tr.flags >> 8) & 0xF0FF;
     1449
     1450        Ctx.ldtr.Sel       = env->ldt.selector;
     1451        Ctx.ldtr.ValidSel  = env->ldt.selector;
     1452        Ctx.ldtr.fFlags    = CPUMSELREG_FLAGS_VALID;
     1453        Ctx.ldtr.u64Base   = env->ldt.base;
     1454        Ctx.ldtr.u32Limit  = env->ldt.limit;
     1455        Ctx.ldtr.Attr.u    = (env->ldt.flags >> 8) & 0xF0FF;
    14521456
    14531457        Ctx.idtr.cbIdt     = env->idt.limit;
     
    14621466        Ctx.eflags.u32     = env->eflags;
    14631467
    1464         Ctx.cs             = env->segs[R_CS].selector;
    1465         Ctx.csHid.u64Base  = env->segs[R_CS].base;
    1466         Ctx.csHid.u32Limit = env->segs[R_CS].limit;
    1467         Ctx.csHid.Attr.u   = (env->segs[R_CS].flags >> 8) & 0xF0FF;
    1468 
    1469         Ctx.ds             = env->segs[R_DS].selector;
    1470         Ctx.dsHid.u64Base  = env->segs[R_DS].base;
    1471         Ctx.dsHid.u32Limit = env->segs[R_DS].limit;
    1472         Ctx.dsHid.Attr.u   = (env->segs[R_DS].flags >> 8) & 0xF0FF;
    1473 
    1474         Ctx.es             = env->segs[R_ES].selector;
    1475         Ctx.esHid.u64Base  = env->segs[R_ES].base;
    1476         Ctx.esHid.u32Limit = env->segs[R_ES].limit;
    1477         Ctx.esHid.Attr.u   = (env->segs[R_ES].flags >> 8) & 0xF0FF;
    1478 
    1479         Ctx.fs             = env->segs[R_FS].selector;
    1480         Ctx.fsHid.u64Base  = env->segs[R_FS].base;
    1481         Ctx.fsHid.u32Limit = env->segs[R_FS].limit;
    1482         Ctx.fsHid.Attr.u   = (env->segs[R_FS].flags >> 8) & 0xF0FF;
    1483 
    1484         Ctx.gs             = env->segs[R_GS].selector;
    1485         Ctx.gsHid.u64Base  = env->segs[R_GS].base;
    1486         Ctx.gsHid.u32Limit = env->segs[R_GS].limit;
    1487         Ctx.gsHid.Attr.u   = (env->segs[R_GS].flags >> 8) & 0xF0FF;
    1488 
    1489         Ctx.ss             = env->segs[R_SS].selector;
    1490         Ctx.ssHid.u64Base  = env->segs[R_SS].base;
    1491         Ctx.ssHid.u32Limit = env->segs[R_SS].limit;
    1492         Ctx.ssHid.Attr.u   = (env->segs[R_SS].flags >> 8) & 0xF0FF;
     1468        Ctx.cs.Sel         = env->segs[R_CS].selector;
     1469        Ctx.cs.ValidSel    = env->segs[R_CS].selector;
     1470        Ctx.cs.fFlags      = CPUMSELREG_FLAGS_VALID;
     1471        Ctx.cs.u64Base     = env->segs[R_CS].base;
     1472        Ctx.cs.u32Limit    = env->segs[R_CS].limit;
     1473        Ctx.cs.Attr.u      = (env->segs[R_CS].flags >> 8) & 0xF0FF;
     1474
     1475        Ctx.ds.Sel         = env->segs[R_DS].selector;
     1476        Ctx.ds.ValidSel    = env->segs[R_DS].selector;
     1477        Ctx.ds.fFlags      = CPUMSELREG_FLAGS_VALID;
     1478        Ctx.ds.u64Base     = env->segs[R_DS].base;
     1479        Ctx.ds.u32Limit    = env->segs[R_DS].limit;
     1480        Ctx.ds.Attr.u      = (env->segs[R_DS].flags >> 8) & 0xF0FF;
     1481
     1482        Ctx.es.Sel         = env->segs[R_ES].selector;
     1483        Ctx.es.ValidSel    = env->segs[R_ES].selector;
     1484        Ctx.es.fFlags      = CPUMSELREG_FLAGS_VALID;
     1485        Ctx.es.u64Base     = env->segs[R_ES].base;
     1486        Ctx.es.u32Limit    = env->segs[R_ES].limit;
     1487        Ctx.es.Attr.u      = (env->segs[R_ES].flags >> 8) & 0xF0FF;
     1488
     1489        Ctx.fs.Sel         = env->segs[R_FS].selector;
     1490        Ctx.fs.ValidSel    = env->segs[R_FS].selector;
     1491        Ctx.fs.fFlags      = CPUMSELREG_FLAGS_VALID;
     1492        Ctx.fs.u64Base     = env->segs[R_FS].base;
     1493        Ctx.fs.u32Limit    = env->segs[R_FS].limit;
     1494        Ctx.fs.Attr.u      = (env->segs[R_FS].flags >> 8) & 0xF0FF;
     1495
     1496        Ctx.gs.Sel         = env->segs[R_GS].selector;
     1497        Ctx.gs.ValidSel    = env->segs[R_GS].selector;
     1498        Ctx.gs.fFlags      = CPUMSELREG_FLAGS_VALID;
     1499        Ctx.gs.u64Base     = env->segs[R_GS].base;
     1500        Ctx.gs.u32Limit    = env->segs[R_GS].limit;
     1501        Ctx.gs.Attr.u      = (env->segs[R_GS].flags >> 8) & 0xF0FF;
     1502
     1503        Ctx.ss.Sel         = env->segs[R_SS].selector;
     1504        Ctx.ss.ValidSel    = env->segs[R_SS].selector;
     1505        Ctx.ss.fFlags      = CPUMSELREG_FLAGS_VALID;
     1506        Ctx.ss.u64Base     = env->segs[R_SS].base;
     1507        Ctx.ss.u32Limit    = env->segs[R_SS].limit;
     1508        Ctx.ss.Attr.u      = (env->segs[R_SS].flags >> 8) & 0xF0FF;
    14931509
    14941510        Ctx.msrEFER        = env->efer;
     
    22612277        if (fFlags & CPUM_CHANGED_LDTR)
    22622278        {
    2263             if (fHiddenSelRegsValid)
     2279            if (fHiddenSelRegsValid || (pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID))
    22642280            {
    2265                 pVM->rem.s.Env.ldt.selector = pCtx->ldtr;
    2266                 pVM->rem.s.Env.ldt.base     = pCtx->ldtrHid.u64Base;
    2267                 pVM->rem.s.Env.ldt.limit    = pCtx->ldtrHid.u32Limit;
    2268                 pVM->rem.s.Env.ldt.flags    = (pCtx->ldtrHid.Attr.u << 8) & 0xFFFFFF;
     2281                pVM->rem.s.Env.ldt.selector = pCtx->ldtr.Sel;
     2282                pVM->rem.s.Env.ldt.base     = pCtx->ldtr.u64Base;
     2283                pVM->rem.s.Env.ldt.limit    = pCtx->ldtr.u32Limit;
     2284                pVM->rem.s.Env.ldt.flags    = (pCtx->ldtr.Attr.u << 8) & 0xFFFFFF;
    22692285            }
    22702286            else
    2271                 sync_ldtr(&pVM->rem.s.Env, pCtx->ldtr);
     2287                sync_ldtr(&pVM->rem.s.Env, pCtx->ldtr.Sel);
    22722288        }
    22732289
     
    22912307     * Sync TR unconditionally to make life simpler.
    22922308     */
    2293     pVM->rem.s.Env.tr.selector = pCtx->tr;
    2294     pVM->rem.s.Env.tr.base     = pCtx->trHid.u64Base;
    2295     pVM->rem.s.Env.tr.limit    = pCtx->trHid.u32Limit;
    2296     pVM->rem.s.Env.tr.flags    = (pCtx->trHid.Attr.u << 8) & 0xFFFFFF;
     2309    pVM->rem.s.Env.tr.selector = pCtx->tr.Sel;
     2310    pVM->rem.s.Env.tr.base     = pCtx->tr.u64Base;
     2311    pVM->rem.s.Env.tr.limit    = pCtx->tr.u32Limit;
     2312    pVM->rem.s.Env.tr.flags    = (pCtx->tr.Attr.u << 8) & 0xFFFFFF;
    22972313    /* Note! do_interrupt will fault if the busy flag is still set... */
    2298     pVM->rem.s.Env.tr.flags &= ~DESC_TSS_BUSY_MASK;
     2314    pVM->rem.s.Env.tr.flags   &= ~DESC_TSS_BUSY_MASK;
    22992315
    23002316    /*
     
    23172333        cpu_x86_set_cpl(&pVM->rem.s.Env, uCpl);
    23182334
    2319         cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_CS, pCtx->cs, pCtx->csHid.u64Base, pCtx->csHid.u32Limit, (pCtx->csHid.Attr.u << 8) & 0xFFFFFF);
    2320         cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_SS, pCtx->ss, pCtx->ssHid.u64Base, pCtx->ssHid.u32Limit, (pCtx->ssHid.Attr.u << 8) & 0xFFFFFF);
    2321         cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_DS, pCtx->ds, pCtx->dsHid.u64Base, pCtx->dsHid.u32Limit, (pCtx->dsHid.Attr.u << 8) & 0xFFFFFF);
    2322         cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_ES, pCtx->es, pCtx->esHid.u64Base, pCtx->esHid.u32Limit, (pCtx->esHid.Attr.u << 8) & 0xFFFFFF);
    2323         cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_FS, pCtx->fs, pCtx->fsHid.u64Base, pCtx->fsHid.u32Limit, (pCtx->fsHid.Attr.u << 8) & 0xFFFFFF);
    2324         cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_GS, pCtx->gs, pCtx->gsHid.u64Base, pCtx->gsHid.u32Limit, (pCtx->gsHid.Attr.u << 8) & 0xFFFFFF);
     2335        cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_CS, pCtx->cs.Sel, pCtx->cs.u64Base, pCtx->cs.u32Limit, (pCtx->cs.Attr.u << 8) & 0xFFFFFF);
     2336        cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_SS, pCtx->ss.Sel, pCtx->ss.u64Base, pCtx->ss.u32Limit, (pCtx->ss.Attr.u << 8) & 0xFFFFFF);
     2337        cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_DS, pCtx->ds.Sel, pCtx->ds.u64Base, pCtx->ds.u32Limit, (pCtx->ds.Attr.u << 8) & 0xFFFFFF);
     2338        cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_ES, pCtx->es.Sel, pCtx->es.u64Base, pCtx->es.u32Limit, (pCtx->es.Attr.u << 8) & 0xFFFFFF);
     2339        cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_FS, pCtx->fs.Sel, pCtx->fs.u64Base, pCtx->fs.u32Limit, (pCtx->fs.Attr.u << 8) & 0xFFFFFF);
     2340        cpu_x86_load_seg_cache(&pVM->rem.s.Env, R_GS, pCtx->gs.Sel, pCtx->gs.u64Base, pCtx->gs.u32Limit, (pCtx->gs.Attr.u << 8) & 0xFFFFFF);
    23252341    }
    23262342    else
    23272343    {
    23282344        /* In 'normal' raw mode we don't have access to the hidden selector registers. */
    2329         if (pVM->rem.s.Env.segs[R_SS].selector != pCtx->ss)
     2345        /** @todo use hidden registers when possible and make CPUM/someone do the
     2346         *        reading of lazily maintained hidden registers. */
     2347        if (pVM->rem.s.Env.segs[R_SS].selector != pCtx->ss.Sel)
    23302348        {
    2331             Log2(("REMR3State: SS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_SS].selector, pCtx->ss));
     2349            Log2(("REMR3State: SS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_SS].selector, pCtx->ss.Sel));
    23322350
    23332351            cpu_x86_set_cpl(&pVM->rem.s.Env, uCpl);
    2334             sync_seg(&pVM->rem.s.Env, R_SS, pCtx->ss);
     2352            sync_seg(&pVM->rem.s.Env, R_SS, pCtx->ss.Sel);
    23352353#ifdef VBOX_WITH_STATISTICS
    23362354            if (pVM->rem.s.Env.segs[R_SS].newselector)
     
    23432361            pVM->rem.s.Env.segs[R_SS].newselector = 0;
    23442362
    2345         if (pVM->rem.s.Env.segs[R_ES].selector != pCtx->es)
     2363        if (pVM->rem.s.Env.segs[R_ES].selector != pCtx->es.Sel)
    23462364        {
    2347             Log2(("REMR3State: ES changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_ES].selector, pCtx->es));
    2348             sync_seg(&pVM->rem.s.Env, R_ES, pCtx->es);
     2365            Log2(("REMR3State: ES changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_ES].selector, pCtx->es.Sel));
     2366            sync_seg(&pVM->rem.s.Env, R_ES, pCtx->es.Sel);
    23492367#ifdef VBOX_WITH_STATISTICS
    23502368            if (pVM->rem.s.Env.segs[R_ES].newselector)
     
    23572375            pVM->rem.s.Env.segs[R_ES].newselector = 0;
    23582376
    2359         if (pVM->rem.s.Env.segs[R_CS].selector != pCtx->cs)
     2377        if (pVM->rem.s.Env.segs[R_CS].selector != pCtx->cs.Sel)
    23602378        {
    2361             Log2(("REMR3State: CS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_CS].selector, pCtx->cs));
    2362             sync_seg(&pVM->rem.s.Env, R_CS, pCtx->cs);
     2379            Log2(("REMR3State: CS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_CS].selector, pCtx->cs.Sel));
     2380            sync_seg(&pVM->rem.s.Env, R_CS, pCtx->cs.Sel);
    23632381#ifdef VBOX_WITH_STATISTICS
    23642382            if (pVM->rem.s.Env.segs[R_CS].newselector)
     
    23712389            pVM->rem.s.Env.segs[R_CS].newselector = 0;
    23722390
    2373         if (pVM->rem.s.Env.segs[R_DS].selector != pCtx->ds)
     2391        if (pVM->rem.s.Env.segs[R_DS].selector != pCtx->ds.Sel)
    23742392        {
    2375             Log2(("REMR3State: DS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_DS].selector, pCtx->ds));
    2376             sync_seg(&pVM->rem.s.Env, R_DS, pCtx->ds);
     2393            Log2(("REMR3State: DS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_DS].selector, pCtx->ds.Sel));
     2394            sync_seg(&pVM->rem.s.Env, R_DS, pCtx->ds.Sel);
    23772395#ifdef VBOX_WITH_STATISTICS
    23782396            if (pVM->rem.s.Env.segs[R_DS].newselector)
     
    23872405    /** @todo need to find a way to communicate potential GDT/LDT changes and thread switches. The selector might
    23882406     * be the same but not the base/limit. */
    2389         if (pVM->rem.s.Env.segs[R_FS].selector != pCtx->fs)
     2407        if (pVM->rem.s.Env.segs[R_FS].selector != pCtx->fs.Sel)
    23902408        {
    2391             Log2(("REMR3State: FS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_FS].selector, pCtx->fs));
    2392             sync_seg(&pVM->rem.s.Env, R_FS, pCtx->fs);
     2409            Log2(("REMR3State: FS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_FS].selector, pCtx->fs.Sel));
     2410            sync_seg(&pVM->rem.s.Env, R_FS, pCtx->fs.Sel);
    23932411#ifdef VBOX_WITH_STATISTICS
    23942412            if (pVM->rem.s.Env.segs[R_FS].newselector)
     
    24012419            pVM->rem.s.Env.segs[R_FS].newselector = 0;
    24022420
    2403         if (pVM->rem.s.Env.segs[R_GS].selector != pCtx->gs)
     2421        if (pVM->rem.s.Env.segs[R_GS].selector != pCtx->gs.Sel)
    24042422        {
    2405             Log2(("REMR3State: GS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_GS].selector, pCtx->gs));
    2406             sync_seg(&pVM->rem.s.Env, R_GS, pCtx->gs);
     2423            Log2(("REMR3State: GS changed from %04x to %04x!\n", pVM->rem.s.Env.segs[R_GS].selector, pCtx->gs.Sel));
     2424            sync_seg(&pVM->rem.s.Env, R_GS, pCtx->gs.Sel);
    24072425#ifdef VBOX_WITH_STATISTICS
    24082426            if (pVM->rem.s.Env.segs[R_GS].newselector)
     
    25802598#endif
    25812599
    2582     pCtx->ss            = pVM->rem.s.Env.segs[R_SS].selector;
    2583 
    2584 #ifdef VBOX_WITH_STATISTICS
    2585     if (pVM->rem.s.Env.segs[R_SS].newselector)
    2586     {
    2587         STAM_COUNTER_INC(&gStatSelOutOfSyncStateBack[R_SS]);
    2588     }
    2589     if (pVM->rem.s.Env.segs[R_GS].newselector)
    2590     {
    2591         STAM_COUNTER_INC(&gStatSelOutOfSyncStateBack[R_GS]);
    2592     }
    2593     if (pVM->rem.s.Env.segs[R_FS].newselector)
    2594     {
    2595         STAM_COUNTER_INC(&gStatSelOutOfSyncStateBack[R_FS]);
    2596     }
    2597     if (pVM->rem.s.Env.segs[R_ES].newselector)
    2598     {
    2599         STAM_COUNTER_INC(&gStatSelOutOfSyncStateBack[R_ES]);
    2600     }
    2601     if (pVM->rem.s.Env.segs[R_DS].newselector)
    2602     {
    2603         STAM_COUNTER_INC(&gStatSelOutOfSyncStateBack[R_DS]);
    2604     }
    2605     if (pVM->rem.s.Env.segs[R_CS].newselector)
    2606     {
    2607         STAM_COUNTER_INC(&gStatSelOutOfSyncStateBack[R_CS]);
    2608     }
    2609 #endif
    2610     pCtx->gs            = pVM->rem.s.Env.segs[R_GS].selector;
    2611     pCtx->fs            = pVM->rem.s.Env.segs[R_FS].selector;
    2612     pCtx->es            = pVM->rem.s.Env.segs[R_ES].selector;
    2613     pCtx->ds            = pVM->rem.s.Env.segs[R_DS].selector;
    2614     pCtx->cs            = pVM->rem.s.Env.segs[R_CS].selector;
     2600#define SYNC_BACK_SREG(a_sreg, a_SREG) \
     2601        do \
     2602        { \
     2603            pCtx->a_sreg.Sel = pVM->rem.s.Env.segs[R_##a_SREG].selector; \
     2604            if (!pVM->rem.s.Env.segs[R_SS].newselector) \
     2605            { \
     2606                pCtx->a_sreg.ValidSel = pVM->rem.s.Env.segs[R_##a_SREG].selector; \
     2607                pCtx->a_sreg.fFlags   = CPUMSELREG_FLAGS_VALID; \
     2608                pCtx->a_sreg.u64Base  = pVM->rem.s.Env.segs[R_##a_SREG].base; \
     2609                pCtx->a_sreg.u32Limit = pVM->rem.s.Env.segs[R_##a_SREG].limit; \
     2610                /* Note! QEmu saves the 2nd dword of the descriptor; we should store the attribute word only! */ \
     2611                pCtx->a_sreg.Attr.u   = (pVM->rem.s.Env.segs[R_##a_SREG].flags >> 8) & 0xF0FF; \
     2612            } \
     2613            else \
     2614            { \
     2615                pCtx->a_sreg.fFlags = 0; \
     2616                STAM_COUNTER_INC(&gStatSelOutOfSyncStateBack[R_##a_SREG]); \
     2617            } \
     2618        } while (0)
     2619
     2620    SYNC_BACK_SREG(es, ES);
     2621    SYNC_BACK_SREG(cs, CS);
     2622    SYNC_BACK_SREG(ss, SS);
     2623    SYNC_BACK_SREG(ds, DS);
     2624    SYNC_BACK_SREG(fs, FS);
     2625    SYNC_BACK_SREG(gs, GS);
    26152626
    26162627#ifdef TARGET_X86_64
     
    26482659    }
    26492660
    2650     if (    pCtx->ldtr             != pVM->rem.s.Env.ldt.selector
    2651         ||  pCtx->ldtrHid.u64Base  != pVM->rem.s.Env.ldt.base
    2652         ||  pCtx->ldtrHid.u32Limit != pVM->rem.s.Env.ldt.limit
    2653         ||  pCtx->ldtrHid.Attr.u   != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF))
    2654     {
    2655         pCtx->ldtr              = pVM->rem.s.Env.ldt.selector;
    2656         pCtx->ldtrHid.u64Base   = pVM->rem.s.Env.ldt.base;
    2657         pCtx->ldtrHid.u32Limit  = pVM->rem.s.Env.ldt.limit;
    2658         pCtx->ldtrHid.Attr.u    = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;
     2661    if (    pCtx->ldtr.Sel      != pVM->rem.s.Env.ldt.selector
     2662        ||  pCtx->ldtr.ValidSel != pVM->rem.s.Env.ldt.selector
     2663        ||  pCtx->ldtr.u64Base  != pVM->rem.s.Env.ldt.base
     2664        ||  pCtx->ldtr.u32Limit != pVM->rem.s.Env.ldt.limit
     2665        ||  pCtx->ldtr.Attr.u   != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF)
     2666        ||  !(pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID)
     2667       )
     2668    {
     2669        pCtx->ldtr.Sel      = pVM->rem.s.Env.ldt.selector;
     2670        pCtx->ldtr.ValidSel = pVM->rem.s.Env.ldt.selector;
     2671        pCtx->ldtr.fFlags   = CPUMSELREG_FLAGS_VALID;
     2672        pCtx->ldtr.u64Base  = pVM->rem.s.Env.ldt.base;
     2673        pCtx->ldtr.u32Limit = pVM->rem.s.Env.ldt.limit;
     2674        pCtx->ldtr.Attr.u   = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;
    26592675        STAM_COUNTER_INC(&gStatREMLDTRChange);
    26602676        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
    26612677    }
    26622678
    2663     if (    pCtx->tr             != pVM->rem.s.Env.tr.selector
    2664         ||  pCtx->trHid.u64Base  != pVM->rem.s.Env.tr.base
    2665         ||  pCtx->trHid.u32Limit != pVM->rem.s.Env.tr.limit
     2679    if (    pCtx->tr.Sel      != pVM->rem.s.Env.tr.selector
     2680        ||  pCtx->tr.ValidSel != pVM->rem.s.Env.tr.selector
     2681        ||  pCtx->tr.u64Base  != pVM->rem.s.Env.tr.base
     2682        ||  pCtx->tr.u32Limit != pVM->rem.s.Env.tr.limit
    26662683            /* Qemu and AMD/Intel have different ideas about the busy flag ... */
    2667         ||  pCtx->trHid.Attr.u   != (  (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF
     2684        ||  pCtx->tr.Attr.u   != (  (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF
    26682685                                     ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8
    2669                                      : 0) )
     2686                                     : 0)
     2687        ||  !(pCtx->tr.fFlags & CPUMSELREG_FLAGS_VALID)
     2688       )
    26702689    {
    26712690        Log(("REM: TR changed! %#x{%#llx,%#x,%#x} -> %#x{%llx,%#x,%#x}\n",
    2672              pCtx->tr, pCtx->trHid.u64Base, pCtx->trHid.u32Limit, pCtx->trHid.Attr.u,
     2691             pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
    26732692             pVM->rem.s.Env.tr.selector, (uint64_t)pVM->rem.s.Env.tr.base, pVM->rem.s.Env.tr.limit,
    26742693             (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8 : 0));
    2675         pCtx->tr                = pVM->rem.s.Env.tr.selector;
    2676         pCtx->trHid.u64Base     = pVM->rem.s.Env.tr.base;
    2677         pCtx->trHid.u32Limit    = pVM->rem.s.Env.tr.limit;
    2678         pCtx->trHid.Attr.u      = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;
    2679         if (pCtx->trHid.Attr.u)
    2680             pCtx->trHid.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
     2694        pCtx->tr.Sel        = pVM->rem.s.Env.tr.selector;
     2695        pCtx->tr.ValidSel   = pVM->rem.s.Env.tr.selector;
     2696        pCtx->tr.fFlags     = CPUMSELREG_FLAGS_VALID;
     2697        pCtx->tr.u64Base    = pVM->rem.s.Env.tr.base;
     2698        pCtx->tr.u32Limit   = pVM->rem.s.Env.tr.limit;
     2699        pCtx->tr.Attr.u     = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;
     2700        if (pCtx->tr.Attr.u)
     2701            pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
    26812702        STAM_COUNTER_INC(&gStatREMTRChange);
    26822703        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
    26832704    }
    2684 
    2685     /** @todo These values could still be out of sync! */
    2686     pCtx->csHid.u64Base    = pVM->rem.s.Env.segs[R_CS].base;
    2687     pCtx->csHid.u32Limit   = pVM->rem.s.Env.segs[R_CS].limit;
    2688     /* Note! QEmu saves the 2nd dword of the descriptor; we should store the attribute word only! */
    2689     pCtx->csHid.Attr.u     = (pVM->rem.s.Env.segs[R_CS].flags >> 8) & 0xF0FF;
    2690 
    2691     pCtx->dsHid.u64Base    = pVM->rem.s.Env.segs[R_DS].base;
    2692     pCtx->dsHid.u32Limit   = pVM->rem.s.Env.segs[R_DS].limit;
    2693     pCtx->dsHid.Attr.u     = (pVM->rem.s.Env.segs[R_DS].flags >> 8) & 0xF0FF;
    2694 
    2695     pCtx->esHid.u64Base    = pVM->rem.s.Env.segs[R_ES].base;
    2696     pCtx->esHid.u32Limit   = pVM->rem.s.Env.segs[R_ES].limit;
    2697     pCtx->esHid.Attr.u     = (pVM->rem.s.Env.segs[R_ES].flags >> 8) & 0xF0FF;
    2698 
    2699     pCtx->fsHid.u64Base    = pVM->rem.s.Env.segs[R_FS].base;
    2700     pCtx->fsHid.u32Limit   = pVM->rem.s.Env.segs[R_FS].limit;
    2701     pCtx->fsHid.Attr.u     = (pVM->rem.s.Env.segs[R_FS].flags >> 8) & 0xF0FF;
    2702 
    2703     pCtx->gsHid.u64Base    = pVM->rem.s.Env.segs[R_GS].base;
    2704     pCtx->gsHid.u32Limit   = pVM->rem.s.Env.segs[R_GS].limit;
    2705     pCtx->gsHid.Attr.u     = (pVM->rem.s.Env.segs[R_GS].flags >> 8) & 0xF0FF;
    2706 
    2707     pCtx->ssHid.u64Base    = pVM->rem.s.Env.segs[R_SS].base;
    2708     pCtx->ssHid.u32Limit   = pVM->rem.s.Env.segs[R_SS].limit;
    2709     pCtx->ssHid.Attr.u     = (pVM->rem.s.Env.segs[R_SS].flags >> 8) & 0xF0FF;
    27102705
    27112706    /* Sysenter MSR */
     
    28452840#endif
    28462841
    2847     pCtx->ss            = pVM->rem.s.Env.segs[R_SS].selector;
    2848 
    2849     pCtx->gs            = pVM->rem.s.Env.segs[R_GS].selector;
    2850     pCtx->fs            = pVM->rem.s.Env.segs[R_FS].selector;
    2851     pCtx->es            = pVM->rem.s.Env.segs[R_ES].selector;
    2852     pCtx->ds            = pVM->rem.s.Env.segs[R_DS].selector;
    2853     pCtx->cs            = pVM->rem.s.Env.segs[R_CS].selector;
     2842    SYNC_BACK_SREG(es, ES);
     2843    SYNC_BACK_SREG(cs, CS);
     2844    SYNC_BACK_SREG(ss, SS);
     2845    SYNC_BACK_SREG(ds, DS);
     2846    SYNC_BACK_SREG(fs, FS);
     2847    SYNC_BACK_SREG(gs, GS);
    28542848
    28552849#ifdef TARGET_X86_64
     
    28872881    }
    28882882
    2889     if (    pCtx->ldtr             != pVM->rem.s.Env.ldt.selector
    2890         ||  pCtx->ldtrHid.u64Base  != pVM->rem.s.Env.ldt.base
    2891         ||  pCtx->ldtrHid.u32Limit != pVM->rem.s.Env.ldt.limit
    2892         ||  pCtx->ldtrHid.Attr.u   != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF))
    2893     {
    2894         pCtx->ldtr              = pVM->rem.s.Env.ldt.selector;
    2895         pCtx->ldtrHid.u64Base   = pVM->rem.s.Env.ldt.base;
    2896         pCtx->ldtrHid.u32Limit  = pVM->rem.s.Env.ldt.limit;
    2897         pCtx->ldtrHid.Attr.u    = (pVM->rem.s.Env.ldt.flags >> 8) & 0xFFFF;
     2883    if (    pCtx->ldtr.Sel      != pVM->rem.s.Env.ldt.selector
     2884        ||  pCtx->ldtr.ValidSel != pVM->rem.s.Env.ldt.selector
     2885        ||  pCtx->ldtr.u64Base  != pVM->rem.s.Env.ldt.base
     2886        ||  pCtx->ldtr.u32Limit != pVM->rem.s.Env.ldt.limit
     2887        ||  pCtx->ldtr.Attr.u   != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF)
     2888        ||  !(pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID)
     2889       )
     2890    {
     2891        pCtx->ldtr.Sel      = pVM->rem.s.Env.ldt.selector;
     2892        pCtx->ldtr.ValidSel = pVM->rem.s.Env.ldt.selector;
     2893        pCtx->ldtr.fFlags   = CPUMSELREG_FLAGS_VALID;
     2894        pCtx->ldtr.u64Base  = pVM->rem.s.Env.ldt.base;
     2895        pCtx->ldtr.u32Limit = pVM->rem.s.Env.ldt.limit;
     2896        pCtx->ldtr.Attr.u   = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;
    28982897        STAM_COUNTER_INC(&gStatREMLDTRChange);
    28992898        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
    29002899    }
    29012900
    2902     if (    pCtx->tr             != pVM->rem.s.Env.tr.selector
    2903         ||  pCtx->trHid.u64Base  != pVM->rem.s.Env.tr.base
    2904         ||  pCtx->trHid.u32Limit != pVM->rem.s.Env.tr.limit
     2901    if (    pCtx->tr.Sel      != pVM->rem.s.Env.tr.selector
     2902        ||  pCtx->tr.ValidSel != pVM->rem.s.Env.tr.selector
     2903        ||  pCtx->tr.u64Base  != pVM->rem.s.Env.tr.base
     2904        ||  pCtx->tr.u32Limit != pVM->rem.s.Env.tr.limit
    29052905            /* Qemu and AMD/Intel have different ideas about the busy flag ... */
    2906         ||  pCtx->trHid.Attr.u   != (  (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF
     2906        ||  pCtx->tr.Attr.u   != (  (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF
    29072907                                     ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8
    2908                                      : 0) )
     2908                                     : 0)
     2909        ||  !(pCtx->tr.fFlags & CPUMSELREG_FLAGS_VALID)
     2910       )
    29092911    {
    29102912        Log(("REM: TR changed! %#x{%#llx,%#x,%#x} -> %#x{%llx,%#x,%#x}\n",
    2911              pCtx->tr, pCtx->trHid.u64Base, pCtx->trHid.u32Limit, pCtx->trHid.Attr.u,
     2913             pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
    29122914             pVM->rem.s.Env.tr.selector, (uint64_t)pVM->rem.s.Env.tr.base, pVM->rem.s.Env.tr.limit,
    29132915             (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8 : 0));
    2914         pCtx->tr                = pVM->rem.s.Env.tr.selector;
    2915         pCtx->trHid.u64Base     = pVM->rem.s.Env.tr.base;
    2916         pCtx->trHid.u32Limit    = pVM->rem.s.Env.tr.limit;
    2917         pCtx->trHid.Attr.u      = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;
    2918         if (pCtx->trHid.Attr.u)
    2919             pCtx->trHid.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
     2916        pCtx->tr.Sel        = pVM->rem.s.Env.tr.selector;
     2917        pCtx->tr.ValidSel   = pVM->rem.s.Env.tr.selector;
     2918        pCtx->tr.fFlags     = CPUMSELREG_FLAGS_VALID;
     2919        pCtx->tr.u64Base    = pVM->rem.s.Env.tr.base;
     2920        pCtx->tr.u32Limit   = pVM->rem.s.Env.tr.limit;
     2921        pCtx->tr.Attr.u     = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;
     2922        if (pCtx->tr.Attr.u)
     2923            pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
    29202924        STAM_COUNTER_INC(&gStatREMTRChange);
    29212925        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
    29222926    }
    2923 
    2924     /** @todo These values could still be out of sync! */
    2925     pCtx->csHid.u64Base    = pVM->rem.s.Env.segs[R_CS].base;
    2926     pCtx->csHid.u32Limit   = pVM->rem.s.Env.segs[R_CS].limit;
    2927     /** @note QEmu saves the 2nd dword of the descriptor; we should store the attribute word only! */
    2928     pCtx->csHid.Attr.u     = (pVM->rem.s.Env.segs[R_CS].flags >> 8) & 0xFFFF;
    2929 
    2930     pCtx->dsHid.u64Base    = pVM->rem.s.Env.segs[R_DS].base;
    2931     pCtx->dsHid.u32Limit   = pVM->rem.s.Env.segs[R_DS].limit;
    2932     pCtx->dsHid.Attr.u     = (pVM->rem.s.Env.segs[R_DS].flags >> 8) & 0xFFFF;
    2933 
    2934     pCtx->esHid.u64Base    = pVM->rem.s.Env.segs[R_ES].base;
    2935     pCtx->esHid.u32Limit   = pVM->rem.s.Env.segs[R_ES].limit;
    2936     pCtx->esHid.Attr.u     = (pVM->rem.s.Env.segs[R_ES].flags >> 8) & 0xFFFF;
    2937 
    2938     pCtx->fsHid.u64Base    = pVM->rem.s.Env.segs[R_FS].base;
    2939     pCtx->fsHid.u32Limit   = pVM->rem.s.Env.segs[R_FS].limit;
    2940     pCtx->fsHid.Attr.u     = (pVM->rem.s.Env.segs[R_FS].flags >> 8) & 0xFFFF;
    2941 
    2942     pCtx->gsHid.u64Base    = pVM->rem.s.Env.segs[R_GS].base;
    2943     pCtx->gsHid.u32Limit   = pVM->rem.s.Env.segs[R_GS].limit;
    2944     pCtx->gsHid.Attr.u     = (pVM->rem.s.Env.segs[R_GS].flags >> 8) & 0xFFFF;
    2945 
    2946     pCtx->ssHid.u64Base    = pVM->rem.s.Env.segs[R_SS].base;
    2947     pCtx->ssHid.u32Limit   = pVM->rem.s.Env.segs[R_SS].limit;
    2948     pCtx->ssHid.Attr.u     = (pVM->rem.s.Env.segs[R_SS].flags >> 8) & 0xFFFF;
    29492927
    29502928    /* Sysenter MSR */
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