diff options
-rw-r--r-- | target/i386/tcg/translate.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 4c91944..b8cb716 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -97,6 +97,7 @@ typedef struct DisasContext { #ifndef CONFIG_USER_ONLY uint8_t cpl; /* code priv level */ + uint8_t iopl; /* i/o priv level */ #endif int code32; /* 32 bit code segment */ @@ -116,7 +117,6 @@ typedef struct DisasContext { int addseg; /* non zero if either DS/ES/SS have a non zero base */ int f_st; /* currently unused */ int vm86; /* vm86 mode */ - int iopl; int tf; /* TF cpu flag */ int jmp_opt; /* use direct block chaining for direct jumps */ int repz_opt; /* optimize jumps within repz instructions */ @@ -153,9 +153,11 @@ typedef struct DisasContext { #ifdef CONFIG_USER_ONLY #define PE(S) true #define CPL(S) 3 +#define IOPL(S) 0 #else #define PE(S) (((S)->flags & HF_PE_MASK) != 0) #define CPL(S) ((S)->cpl) +#define IOPL(S) ((S)->iopl) #endif static void gen_eob(DisasContext *s); @@ -629,7 +631,7 @@ static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip, { target_ulong next_eip; - if (PE(s) && (CPL(s) > s->iopl || s->vm86)) { + if (PE(s) && (CPL(s) > IOPL(s) || s->vm86)) { tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); switch (ot) { case MO_8: @@ -1307,7 +1309,7 @@ static bool check_cpl0(DisasContext *s) /* If vm86, check for iopl == 3; if not, raise #GP and return false. */ static bool check_vm86_iopl(DisasContext *s) { - if (!s->vm86 || s->iopl == 3) { + if (!s->vm86 || IOPL(s) == 3) { return true; } gen_exception_gpf(s); @@ -1317,7 +1319,7 @@ static bool check_vm86_iopl(DisasContext *s) /* Check for iopl allowing access; if not, raise #GP and return false. */ static bool check_iopl(DisasContext *s) { - if (s->vm86 ? s->iopl == 3 : CPL(s) <= s->iopl) { + if (s->vm86 ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) { return true; } gen_exception_gpf(s); @@ -6756,7 +6758,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) & 0xffff)); } } else { - if (CPL(s) <= s->iopl) { + if (CPL(s) <= IOPL(s)) { if (dflag != MO_16) { gen_helper_write_eflags(cpu_env, s->T0, tcg_const_i32((TF_MASK | @@ -8474,23 +8476,25 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) CPUX86State *env = cpu->env_ptr; uint32_t flags = dc->base.tb->flags; int cpl = (flags >> HF_CPL_SHIFT) & 3; + int iopl = (flags >> IOPL_SHIFT) & 3; dc->cs_base = dc->base.tb->cs_base; dc->flags = flags; #ifndef CONFIG_USER_ONLY dc->cpl = cpl; + dc->iopl = iopl; #endif /* We make some simplifying assumptions; validate they're correct. */ g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); g_assert(CPL(dc) == cpl); + g_assert(IOPL(dc) == iopl); dc->code32 = (flags >> HF_CS32_SHIFT) & 1; dc->ss32 = (flags >> HF_SS32_SHIFT) & 1; dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1; dc->f_st = 0; dc->vm86 = (flags >> VM_SHIFT) & 1; - dc->iopl = (flags >> IOPL_SHIFT) & 3; dc->tf = (flags >> TF_SHIFT) & 1; dc->cc_op = CC_OP_DYNAMIC; dc->cc_op_dirty = false; |