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