mirror of https://gitee.com/openkylin/qemu.git
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
|
@ -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 (env->eflags & VM_MASK) {
|
||||
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);
|
||||
cpu_x86_set_cpl(env, dpl);
|
||||
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
|
||||
|
@ -911,6 +911,12 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
|
|||
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) {
|
||||
ss = 0 | dpl;
|
||||
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);
|
||||
cpu_x86_set_cpl(env, dpl);
|
||||
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
|
||||
|
||||
|
@ -960,6 +960,8 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
|||
|
||||
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_load_seg_cache(env, R_CS, selector & 0xfffc,
|
||||
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_S_MASK |
|
||||
DESC_W_MASK | DESC_A_MASK);
|
||||
env->eflags &= ~env->fmask;
|
||||
cpu_load_eflags(env, env->eflags, 0);
|
||||
if (code64) {
|
||||
env->eip = env->lstar;
|
||||
} else {
|
||||
|
@ -982,6 +982,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
|||
} else {
|
||||
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_load_seg_cache(env, R_CS, selector & 0xfffc,
|
||||
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_S_MASK |
|
||||
DESC_W_MASK | DESC_A_MASK);
|
||||
env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
|
||||
env->eip = (uint32_t)env->star;
|
||||
}
|
||||
}
|
||||
|
@ -1014,6 +1014,9 @@ void helper_sysret(CPUX86State *env, int dflag)
|
|||
}
|
||||
selector = (env->star >> 48) & 0xffff;
|
||||
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) {
|
||||
cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
|
||||
0, 0xffffffff,
|
||||
|
@ -1035,11 +1038,9 @@ void helper_sysret(CPUX86State *env, int dflag)
|
|||
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
||||
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
|
||||
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);
|
||||
} else {
|
||||
env->eflags |= IF_MASK;
|
||||
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
|
||||
0, 0xffffffff,
|
||||
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_S_MASK | (3 << DESC_DPL_SHIFT) |
|
||||
DESC_W_MASK | DESC_A_MASK);
|
||||
env->eflags |= IF_MASK;
|
||||
cpu_x86_set_cpl(env, 3);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue