mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-02 21:32:52 +00:00
target-i386: set eflags prior to calling cpu_x86_load_seg_cache() in seg_helper.c
The cpu_x86_load_seg_cache() function inspects eflags, so make sure all changes to eflags are done prior to loading the segment caches. Signed-off-by: Kevin O'Connor <kevin@koconnor.net> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
010e639a8d
commit
fd460606fd
1 changed files with 19 additions and 19 deletions
|
@ -739,6 +739,12 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* interrupt gate clear IF mask */
|
||||||
|
if ((type & 1) == 0) {
|
||||||
|
env->eflags &= ~IF_MASK;
|
||||||
|
}
|
||||||
|
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
|
||||||
|
|
||||||
if (new_stack) {
|
if (new_stack) {
|
||||||
if (env->eflags & VM_MASK) {
|
if (env->eflags & VM_MASK) {
|
||||||
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);
|
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);
|
||||||
|
@ -759,12 +765,6 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
|
||||||
e2);
|
e2);
|
||||||
cpu_x86_set_cpl(env, dpl);
|
cpu_x86_set_cpl(env, dpl);
|
||||||
env->eip = offset;
|
env->eip = offset;
|
||||||
|
|
||||||
/* interrupt gate clear IF mask */
|
|
||||||
if ((type & 1) == 0) {
|
|
||||||
env->eflags &= ~IF_MASK;
|
|
||||||
}
|
|
||||||
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TARGET_X86_64
|
#ifdef TARGET_X86_64
|
||||||
|
@ -911,6 +911,12 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
|
||||||
PUSHQ(esp, error_code);
|
PUSHQ(esp, error_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* interrupt gate clear IF mask */
|
||||||
|
if ((type & 1) == 0) {
|
||||||
|
env->eflags &= ~IF_MASK;
|
||||||
|
}
|
||||||
|
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
|
||||||
|
|
||||||
if (new_stack) {
|
if (new_stack) {
|
||||||
ss = 0 | dpl;
|
ss = 0 | dpl;
|
||||||
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
|
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
|
||||||
|
@ -924,12 +930,6 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
|
||||||
e2);
|
e2);
|
||||||
cpu_x86_set_cpl(env, dpl);
|
cpu_x86_set_cpl(env, dpl);
|
||||||
env->eip = offset;
|
env->eip = offset;
|
||||||
|
|
||||||
/* interrupt gate clear IF mask */
|
|
||||||
if ((type & 1) == 0) {
|
|
||||||
env->eflags &= ~IF_MASK;
|
|
||||||
}
|
|
||||||
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -960,6 +960,8 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
||||||
|
|
||||||
code64 = env->hflags & HF_CS64_MASK;
|
code64 = env->hflags & HF_CS64_MASK;
|
||||||
|
|
||||||
|
env->eflags &= ~env->fmask;
|
||||||
|
cpu_load_eflags(env, env->eflags, 0);
|
||||||
cpu_x86_set_cpl(env, 0);
|
cpu_x86_set_cpl(env, 0);
|
||||||
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
|
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
|
||||||
0, 0xffffffff,
|
0, 0xffffffff,
|
||||||
|
@ -972,8 +974,6 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
||||||
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
||||||
DESC_S_MASK |
|
DESC_S_MASK |
|
||||||
DESC_W_MASK | DESC_A_MASK);
|
DESC_W_MASK | DESC_A_MASK);
|
||||||
env->eflags &= ~env->fmask;
|
|
||||||
cpu_load_eflags(env, env->eflags, 0);
|
|
||||||
if (code64) {
|
if (code64) {
|
||||||
env->eip = env->lstar;
|
env->eip = env->lstar;
|
||||||
} else {
|
} else {
|
||||||
|
@ -982,6 +982,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
||||||
} else {
|
} else {
|
||||||
env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
|
env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
|
||||||
|
|
||||||
|
env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
|
||||||
cpu_x86_set_cpl(env, 0);
|
cpu_x86_set_cpl(env, 0);
|
||||||
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
|
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
|
||||||
0, 0xffffffff,
|
0, 0xffffffff,
|
||||||
|
@ -993,7 +994,6 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
||||||
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
||||||
DESC_S_MASK |
|
DESC_S_MASK |
|
||||||
DESC_W_MASK | DESC_A_MASK);
|
DESC_W_MASK | DESC_A_MASK);
|
||||||
env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
|
|
||||||
env->eip = (uint32_t)env->star;
|
env->eip = (uint32_t)env->star;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1014,6 +1014,9 @@ void helper_sysret(CPUX86State *env, int dflag)
|
||||||
}
|
}
|
||||||
selector = (env->star >> 48) & 0xffff;
|
selector = (env->star >> 48) & 0xffff;
|
||||||
if (env->hflags & HF_LMA_MASK) {
|
if (env->hflags & HF_LMA_MASK) {
|
||||||
|
cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK
|
||||||
|
| ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK |
|
||||||
|
NT_MASK);
|
||||||
if (dflag == 2) {
|
if (dflag == 2) {
|
||||||
cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
|
cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
|
||||||
0, 0xffffffff,
|
0, 0xffffffff,
|
||||||
|
@ -1035,11 +1038,9 @@ void helper_sysret(CPUX86State *env, int dflag)
|
||||||
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
||||||
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
|
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
|
||||||
DESC_W_MASK | DESC_A_MASK);
|
DESC_W_MASK | DESC_A_MASK);
|
||||||
cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK
|
|
||||||
| ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK |
|
|
||||||
NT_MASK);
|
|
||||||
cpu_x86_set_cpl(env, 3);
|
cpu_x86_set_cpl(env, 3);
|
||||||
} else {
|
} else {
|
||||||
|
env->eflags |= IF_MASK;
|
||||||
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
|
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
|
||||||
0, 0xffffffff,
|
0, 0xffffffff,
|
||||||
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
||||||
|
@ -1051,7 +1052,6 @@ void helper_sysret(CPUX86State *env, int dflag)
|
||||||
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
||||||
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
|
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
|
||||||
DESC_W_MASK | DESC_A_MASK);
|
DESC_W_MASK | DESC_A_MASK);
|
||||||
env->eflags |= IF_MASK;
|
|
||||||
cpu_x86_set_cpl(env, 3);
|
cpu_x86_set_cpl(env, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue