From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56727) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZpeLo-0002US-NW for qemu-devel@nongnu.org; Fri, 23 Oct 2015 11:33:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZpeLl-0001v7-Ke for qemu-devel@nongnu.org; Fri, 23 Oct 2015 11:33:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53155) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZpeLl-0001uf-DS for qemu-devel@nongnu.org; Fri, 23 Oct 2015 11:33:49 -0400 From: Eduardo Habkost Date: Fri, 23 Oct 2015 13:33:08 -0200 Message-Id: <1445614392-26687-10-git-send-email-ehabkost@redhat.com> In-Reply-To: <1445614392-26687-1-git-send-email-ehabkost@redhat.com> References: <1445614392-26687-1-git-send-email-ehabkost@redhat.com> Subject: [Qemu-devel] [PULL 09/13] target-i386: Check CR4[DE] for processing DR4/DR5 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Maydell Cc: qemu-devel@nongnu.org, Paolo Bonzini , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Richard Henderson From: Richard Henderson Introduce helper_get_dr so that we don't have to put CR4[DE] into the scarce HFLAGS resource. At the same time, rename helper_movl_drN_T0 to helper_set_dr and set the helper flags. Signed-off-by: Richard Henderson Signed-off-by: Eduardo Habkost --- target-i386/bpt_helper.c | 46 +++++++++++++++++++++++++++++++++++++++++----- target-i386/cpu.h | 2 +- target-i386/helper.h | 3 ++- target-i386/translate.c | 10 ++++++---- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c index 117cea2..144cfd4 100644 --- a/target-i386/bpt_helper.c +++ b/target-i386/bpt_helper.c @@ -242,10 +242,11 @@ void helper_single_step(CPUX86State *env) raise_exception(env, EXCP01_DB); } -void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0) +void helper_set_dr(CPUX86State *env, int reg, target_ulong t0) { #ifndef CONFIG_USER_ONLY - if (reg < 4) { + switch (reg) { + case 0: case 1: case 2: case 3: if (hw_breakpoint_enabled(env->dr[7], reg) && hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) { hw_breakpoint_remove(env, reg); @@ -254,14 +255,49 @@ void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0) } else { env->dr[reg] = t0; } - } else if (reg == 7) { + return; + case 4: + if (env->cr[4] & CR4_DE_MASK) { + break; + } + /* fallthru */ + case 6: + env->dr[6] = t0; + return; + case 5: + if (env->cr[4] & CR4_DE_MASK) { + break; + } + /* fallthru */ + case 7: cpu_x86_update_dr7(env, t0); - } else { - env->dr[reg] = t0; + return; } + raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); #endif } +target_ulong helper_get_dr(CPUX86State *env, int reg) +{ + switch (reg) { + case 0: case 1: case 2: case 3: case 6: case 7: + return env->dr[reg]; + case 4: + if (env->cr[4] & CR4_DE_MASK) { + break; + } else { + return env->dr[6]; + } + case 5: + if (env->cr[4] & CR4_DE_MASK) { + break; + } else { + return env->dr[7]; + } + } + raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); +} + /* Check if Port I/O is trapped by a breakpoint. */ void helper_bpt_io(CPUX86State *env, uint32_t port, uint32_t size, target_ulong next_eip) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 0bf6f88..62f7879 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -920,7 +920,7 @@ typedef struct CPUX86State { int error_code; int exception_is_int; target_ulong exception_next_eip; - target_ulong dr[8]; /* debug registers */ + target_ulong dr[8]; /* debug registers; note dr4 and dr5 are unused */ union { struct CPUBreakpoint *cpu_breakpoint[4]; struct CPUWatchpoint *cpu_watchpoint[4]; diff --git a/target-i386/helper.h b/target-i386/helper.h index e9858c0..ecfcfd1 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -40,7 +40,8 @@ DEF_HELPER_2(read_crN, tl, env, int) DEF_HELPER_3(write_crN, void, env, int, tl) DEF_HELPER_2(lmsw, void, env, tl) DEF_HELPER_1(clts, void, env) -DEF_HELPER_3(movl_drN_T0, void, env, int, tl) +DEF_HELPER_FLAGS_3(set_dr, TCG_CALL_NO_WG, void, env, int, tl) +DEF_HELPER_FLAGS_2(get_dr, TCG_CALL_NO_WG, tl, env, int) DEF_HELPER_2(invlpg, void, env, tl) DEF_HELPER_4(enter_level, void, env, int, int, tl) diff --git a/target-i386/translate.c b/target-i386/translate.c index ceed4d1..764b1e4 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7627,18 +7627,20 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, ot = MO_64; else ot = MO_32; - /* XXX: do it dynamically with CR4.DE bit */ - if (reg == 4 || reg == 5 || reg >= 8) + if (reg >= 8) { goto illegal_op; + } if (b & 2) { gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg); gen_op_mov_v_reg(ot, cpu_T[0], rm); - gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]); + tcg_gen_movi_i32(cpu_tmp2_i32, reg); + gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T[0]); gen_jmp_im(s->pc - s->cs_base); gen_eob(s); } else { gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg])); + tcg_gen_movi_i32(cpu_tmp2_i32, reg); + gen_helper_get_dr(cpu_T[0], cpu_env, cpu_tmp2_i32); gen_op_mov_reg_v(ot, rm, cpu_T[0]); } } -- 2.1.0