Revision b6d78bfa helper-i386.c

b/helper-i386.c
189 189
{
190 190
    SegmentCache *dt;
191 191
    uint8_t *ptr, *ssp;
192
    int type, dpl, cpl, selector, ss_dpl;
192
    int type, dpl, selector, ss_dpl;
193 193
    int has_error_code, new_stack, shift;
194 194
    uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2, push_size;
195 195
    uint32_t old_cs, old_ss, old_esp, old_eip;
......
216 216
        break;
217 217
    }
218 218
    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
219
    if (env->eflags & VM_MASK)
220
        cpl = 3;
221
    else
222
        cpl = env->segs[R_CS].selector & 3;
223 219
    /* check privledge if software int */
224
    if (is_int && dpl < cpl)
220
    if (is_int && dpl < env->cpl)
225 221
        raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
226 222
    /* check valid bit */
227 223
    if (!(e2 & DESC_P_MASK))
......
236 232
    if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
237 233
        raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
238 234
    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
239
    if (dpl > cpl)
235
    if (dpl > env->cpl)
240 236
        raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
241 237
    if (!(e2 & DESC_P_MASK))
242 238
        raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
243
    if (!(e2 & DESC_C_MASK) && dpl < cpl) {
239
    if (!(e2 & DESC_C_MASK) && dpl < env->cpl) {
244 240
        /* to inner priviledge */
245 241
        get_ss_esp_from_tss(&ss, &esp, dpl);
246 242
        if ((ss & 0xfffc) == 0)
......
259 255
        if (!(ss_e2 & DESC_P_MASK))
260 256
            raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
261 257
        new_stack = 1;
262
    } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
258
    } else if ((e2 & DESC_C_MASK) || dpl == env->cpl) {
263 259
        /* to same priviledge */
264 260
        new_stack = 0;
265 261
    } else {
......
406 402
{
407 403
    SegmentCache *dt;
408 404
    uint8_t *ptr;
409
    int dpl, cpl;
405
    int dpl;
410 406
    uint32_t e2;
411 407

  
412 408
    dt = &env->idt;
......
414 410
    e2 = ldl(ptr + 4);
415 411
    
416 412
    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
417
    cpl = 3;
418 413
    /* check privledge if software int */
419
    if (is_int && dpl < cpl)
414
    if (is_int && dpl < env->cpl)
420 415
        raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
421 416

  
422 417
    /* Since we emulate only user space, we cannot do more than
......
728 723
                selector, (unsigned long)sc->base, sc->limit, sc->flags);
729 724
#endif
730 725
    }
726
    if (seg_reg == R_CS) {
727
        cpu_x86_set_cpl(env, selector & 3);
728
    }
731 729
    sc->selector = selector;
732 730
}
733 731

  
......
744 742
        raise_exception_err(EXCP0D_GPF, 0);
745 743
    if (load_segment(&e1, &e2, new_cs) != 0)
746 744
        raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
747
    cpl = env->segs[R_CS].selector & 3;
745
    cpl = env->cpl;
748 746
    if (e2 & DESC_S_MASK) {
749 747
        if (!(e2 & DESC_CS_MASK))
750 748
            raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
......
828 826
        raise_exception_err(EXCP0D_GPF, 0);
829 827
    if (load_segment(&e1, &e2, new_cs) != 0)
830 828
        raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
831
    cpl = env->segs[R_CS].selector & 3;
829
    cpl = env->cpl;
832 830
    if (e2 & DESC_S_MASK) {
833 831
        if (!(e2 & DESC_CS_MASK))
834 832
            raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
......
1081 1079
    if (!(e2 & DESC_S_MASK) ||
1082 1080
        !(e2 & DESC_CS_MASK))
1083 1081
        raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
1084
    cpl = env->segs[R_CS].selector & 3;
1082
    cpl = env->cpl;
1085 1083
    rpl = new_cs & 3; 
1086 1084
    if (rpl < cpl)
1087 1085
        raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
......
1158 1156
    /* modify processor state */
1159 1157
    load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK);
1160 1158
    load_seg_vm(R_CS, new_cs);
1159
    cpu_x86_set_cpl(env, 3);
1161 1160
    load_seg_vm(R_SS, new_ss);
1162 1161
    load_seg_vm(R_ES, new_es);
1163 1162
    load_seg_vm(R_DS, new_ds);
1164 1163
    load_seg_vm(R_FS, new_fs);
1165 1164
    load_seg_vm(R_GS, new_gs);
1166
    
1165

  
1167 1166
    env->eip = new_eip;
1168 1167
    env->regs[R_ESP] = new_esp;
1169 1168
}

Also available in: Unified diff