target-i386: fix segment flags for SMM and VM86 mode
With the next patch, these need to be correct or VM86 tasks have the wrong CPL. The flags are basically what the Intel VMX documentation say is mandatory for entry into a VM86 guest. For consistency, SMM ought to have the same flags except with CPL=0. Tested-by: Kevin O'Connor <kevin@koconnor.net> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
87446327cc
commit
b98dbc9095
@ -1004,7 +1004,7 @@ int main(int argc, char **argv)
|
||||
|
||||
#if defined(TARGET_I386)
|
||||
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
|
||||
env->hflags |= HF_PE_MASK;
|
||||
env->hflags |= HF_PE_MASK | HF_CPL_MASK;
|
||||
if (env->features[FEAT_1_EDX] & CPUID_SSE) {
|
||||
env->cr[4] |= CR4_OSFXSR_MASK;
|
||||
env->hflags |= HF_OSFXSR_MASK;
|
||||
|
@ -4052,7 +4052,7 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
#if defined(TARGET_I386)
|
||||
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
|
||||
env->hflags |= HF_PE_MASK;
|
||||
env->hflags |= HF_PE_MASK | HF_CPL_MASK;
|
||||
if (env->features[FEAT_1_EDX] & CPUID_SSE) {
|
||||
env->cr[4] |= CR4_OSFXSR_MASK;
|
||||
env->hflags |= HF_OSFXSR_MASK;
|
||||
|
@ -127,9 +127,11 @@ static int x86_cpu_gdb_load_seg(X86CPU *cpu, int sreg, uint8_t *mem_buf)
|
||||
target_ulong base;
|
||||
|
||||
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
|
||||
int dpl = (env->eflags & VM_MASK) ? 3 : 0;
|
||||
base = selector << 4;
|
||||
limit = 0xffff;
|
||||
flags = 0;
|
||||
flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK | (dpl << DESC_DPL_SHIFT);
|
||||
} else {
|
||||
if (!cpu_x86_get_descr_debug(env, selector, &base, &limit,
|
||||
&flags)) {
|
||||
|
@ -88,8 +88,10 @@ static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1,
|
||||
static inline void load_seg_vm(CPUX86State *env, int seg, int selector)
|
||||
{
|
||||
selector &= 0xffff;
|
||||
cpu_x86_load_seg_cache(env, seg, selector,
|
||||
(selector << 4), 0xffff, 0);
|
||||
|
||||
cpu_x86_load_seg_cache(env, seg, selector, (selector << 4), 0xffff,
|
||||
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK | (3 << DESC_DPL_SHIFT));
|
||||
}
|
||||
|
||||
static inline void get_ss_esp_from_tss(CPUX86State *env, uint32_t *ss_ptr,
|
||||
@ -2465,9 +2467,12 @@ void helper_verw(CPUX86State *env, target_ulong selector1)
|
||||
void cpu_x86_load_seg(CPUX86State *env, int seg_reg, int selector)
|
||||
{
|
||||
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
|
||||
int dpl = (env->eflags & VM_MASK) ? 3 : 0;
|
||||
selector &= 0xffff;
|
||||
cpu_x86_load_seg_cache(env, seg_reg, selector,
|
||||
(selector << 4), 0xffff, 0);
|
||||
(selector << 4), 0xffff,
|
||||
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK | (dpl << DESC_DPL_SHIFT));
|
||||
} else {
|
||||
helper_load_seg(env, seg_reg, selector);
|
||||
}
|
||||
|
@ -171,12 +171,24 @@ void do_smm_enter(X86CPU *cpu)
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
|
||||
cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
|
||||
0xffffffff, 0);
|
||||
cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0);
|
||||
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0);
|
||||
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0);
|
||||
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0);
|
||||
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0);
|
||||
0xffffffff,
|
||||
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK);
|
||||
cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff,
|
||||
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK);
|
||||
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff,
|
||||
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK);
|
||||
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff,
|
||||
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK);
|
||||
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff,
|
||||
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK);
|
||||
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff,
|
||||
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
|
||||
DESC_A_MASK);
|
||||
}
|
||||
|
||||
void helper_rsm(CPUX86State *env)
|
||||
|
Loading…
Reference in New Issue
Block a user