This is in preparation for using the generic emulator here. Some care is needed temporarily to not unduly alter guest register state: The local variable "res" can only go away once this code got fully switched over to using x86_emulate(). Also switch to IS_ERR_VALUE() instead of (incorrectly) open coding it. Signed-off-by: Jan Beulich --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -2343,6 +2343,26 @@ static int priv_op_write_cr(unsigned int return X86EMUL_UNHANDLEABLE; } +static int priv_op_read_dr(unsigned int reg, unsigned long *val, + struct x86_emulate_ctxt *ctxt) +{ + unsigned long res = do_get_debugreg(reg); + + if ( IS_ERR_VALUE(res) ) + return X86EMUL_UNHANDLEABLE; + + *val = res; + + return X86EMUL_OKAY; +} + +static int priv_op_write_dr(unsigned int reg, unsigned long val, + struct x86_emulate_ctxt *ctxt) +{ + return do_set_debugreg(reg, val) == 0 + ? X86EMUL_OKAY : X86EMUL_UNHANDLEABLE; +} + static inline uint64_t guest_misc_enable(uint64_t val) { val &= ~(MSR_IA32_MISC_ENABLE_PERF_AVAIL | @@ -2761,16 +2781,14 @@ static int emulate_privileged_op(struct break; case 0x21: /* MOV DR?, */ { - unsigned long res; opcode = insn_fetch(u8, code_base, eip, code_limit); if ( opcode < 0xc0 ) goto fail; modrm_reg += ((opcode >> 3) & 7) + (lock << 3); modrm_rm |= (opcode >> 0) & 7; - reg = decode_register(modrm_rm, regs, 0); - if ( (res = do_get_debugreg(modrm_reg)) > (unsigned long)-256 ) + if ( priv_op_read_dr(modrm_reg, decode_register(modrm_rm, regs, 0), + NULL) != X86EMUL_OKAY ) goto fail; - *reg = res; break; } @@ -2799,7 +2817,7 @@ static int emulate_privileged_op(struct modrm_reg += ((opcode >> 3) & 7) + (lock << 3); modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); - if ( do_set_debugreg(modrm_reg, *reg) != 0 ) + if ( priv_op_write_dr(modrm_reg, *reg, NULL) != X86EMUL_OKAY ) goto fail; break;