VirtualBox

Changeset 47757 in vbox


Ignore:
Timestamp:
Aug 15, 2013 12:01:05 PM (11 years ago)
Author:
vboxsync
Message:

REM: Corrected task switch order (old task saved first, new task loaded next). Fixed 16-bit task switching bug (offsets into TSS for segment storage were wrong).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/target-i386/op_helper.c

    r47753 r47757  
    463463        old_tss_limit_max = 43;
    464464
     465#ifndef VBOX    /* The old TSS is written first... */
    465466    /* read all the registers from the new TSS */
    466467    if (type & 8) {
     
    489490        new_trap = 0;
    490491    }
     492#endif
    491493
    492494    /* NOTE: we must avoid memory exceptions during the task switch,
     
    528530        for(i = 0; i < 6; i++)
    529531            stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector);
    530 #ifdef VBOX
    531         /* Must store the ldt as it gets reloaded and might have been changed. */
    532         stw_kernel(env->tr.base + 0x60, env->ldt.selector);
    533 #endif
    534532#if defined(VBOX) && defined(DEBUG)
    535533        printf("TSS 32 bits switch\n");
     
    549547        stw_kernel(env->tr.base + (0x12 + 7 * 2), EDI);
    550548        for(i = 0; i < 4; i++)
    551             stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector);
     549            stw_kernel(env->tr.base + (0x22 + i * 2), env->segs[i].selector);
     550    }
     551
    552552#ifdef VBOX
    553         /* Must store the ldt as it gets reloaded and might have been changed. */
    554         stw_kernel(env->tr.base + 0x2a, env->ldt.selector);
    555 #endif
    556     }
     553    /* read all the registers from the new TSS - may be the same as the old one */
     554    if (type & 8) {
     555        /* 32 bit */
     556        new_cr3 = ldl_kernel(tss_base + 0x1c);
     557        new_eip = ldl_kernel(tss_base + 0x20);
     558        new_eflags = ldl_kernel(tss_base + 0x24);
     559        for(i = 0; i < 8; i++)
     560            new_regs[i] = ldl_kernel(tss_base + (0x28 + i * 4));
     561        for(i = 0; i < 6; i++)
     562            new_segs[i] = lduw_kernel(tss_base + (0x48 + i * 4));
     563        new_ldt = lduw_kernel(tss_base + 0x60);
     564        new_trap = ldl_kernel(tss_base + 0x64);
     565    } else {
     566        /* 16 bit */
     567        new_cr3 = 0;
     568        new_eip = lduw_kernel(tss_base + 0x0e);
     569        new_eflags = lduw_kernel(tss_base + 0x10);
     570        for(i = 0; i < 8; i++)
     571            new_regs[i] = lduw_kernel(tss_base + (0x12 + i * 2)) | 0xffff0000;
     572        for(i = 0; i < 4; i++)
     573            new_segs[i] = lduw_kernel(tss_base + (0x22 + i * 2));
     574        new_ldt = lduw_kernel(tss_base + 0x2a);
     575        new_segs[R_FS] = 0;
     576        new_segs[R_GS] = 0;
     577        new_trap = 0;
     578    }
     579#endif
    557580
    558581    /* now if an exception occurs, it will occurs in the next task
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