diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-05-29 21:59:09 +0900 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-07-12 13:16:01 +0300 |
commit | e4f973ae913028bac8c07187e0fd49c1dc08ce58 (patch) | |
tree | 039a3c0bb5776f9d1f7dc5c1766850fd30239ed8 /arch/x86/kvm | |
parent | 9f21ca599cd609502de8a56c1d4c4688d40abb2d (diff) | |
download | linux-next-e4f973ae913028bac8c07187e0fd49c1dc08ce58.tar.gz |
KVM: x86 emulator: Use opcode::execute for XCHG(86/87)
In addition, replace one "goto xchg" with an em_xchg() call.
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/emulate.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d25cfc238b90..c3d071dfe504 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2613,6 +2613,20 @@ static int em_test(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } +static int em_xchg(struct x86_emulate_ctxt *ctxt) +{ + struct decode_cache *c = &ctxt->decode; + + /* Write back the register source. */ + c->src.val = c->dst.val; + write_register_operand(&c->src); + + /* Write back the memory destination with implicit LOCK prefix. */ + c->dst.val = c->src.orig_val; + c->lock_prefix = 1; + return X86EMUL_CONTINUE; +} + static int em_imul(struct x86_emulate_ctxt *ctxt) { struct decode_cache *c = &ctxt->decode; @@ -3144,7 +3158,7 @@ static struct opcode opcode_table[256] = { G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1), G(DstMem | SrcImmByte | ModRM | Group, group1), I2bv(DstMem | SrcReg | ModRM, em_test), - D2bv(DstMem | SrcReg | ModRM | Lock), + I2bv(DstMem | SrcReg | ModRM | Lock, em_xchg), /* 0x88 - 0x8F */ I2bv(DstMem | SrcReg | ModRM | Mov, em_mov), I2bv(DstReg | SrcMem | ModRM | Mov, em_mov), @@ -3882,18 +3896,6 @@ special_insn: if (test_cc(c->b, ctxt->eflags)) jmp_rel(c, c->src.val); break; - case 0x86 ... 0x87: /* xchg */ - xchg: - /* Write back the register source. */ - c->src.val = c->dst.val; - write_register_operand(&c->src); - /* - * Write back the memory destination with implicit LOCK - * prefix. - */ - c->dst.val = c->src.orig_val; - c->lock_prefix = 1; - break; case 0x8c: /* mov r/m, sreg */ if (c->modrm_reg > VCPU_SREG_GS) { rc = emulate_ud(ctxt); @@ -3929,7 +3931,8 @@ special_insn: case 0x90 ... 0x97: /* nop / xchg reg, rax */ if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX]) break; - goto xchg; + rc = em_xchg(ctxt); + break; case 0x98: /* cbw/cwde/cdqe */ switch (c->op_bytes) { case 2: c->dst.val = (s8)c->dst.val; break; |