aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2011-05-29 08:59:09 -0400
committerAvi Kivity <avi@redhat.com>2011-07-12 06:16:01 -0400
commite4f973ae913028bac8c07187e0fd49c1dc08ce58 (patch)
tree039a3c0bb5776f9d1f7dc5c1766850fd30239ed8 /arch/x86/kvm/emulate.c
parent9f21ca599cd609502de8a56c1d4c4688d40abb2d (diff)
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/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c31
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)
2613 return X86EMUL_CONTINUE; 2613 return X86EMUL_CONTINUE;
2614} 2614}
2615 2615
2616static int em_xchg(struct x86_emulate_ctxt *ctxt)
2617{
2618 struct decode_cache *c = &ctxt->decode;
2619
2620 /* Write back the register source. */
2621 c->src.val = c->dst.val;
2622 write_register_operand(&c->src);
2623
2624 /* Write back the memory destination with implicit LOCK prefix. */
2625 c->dst.val = c->src.orig_val;
2626 c->lock_prefix = 1;
2627 return X86EMUL_CONTINUE;
2628}
2629
2616static int em_imul(struct x86_emulate_ctxt *ctxt) 2630static int em_imul(struct x86_emulate_ctxt *ctxt)
2617{ 2631{
2618 struct decode_cache *c = &ctxt->decode; 2632 struct decode_cache *c = &ctxt->decode;
@@ -3144,7 +3158,7 @@ static struct opcode opcode_table[256] = {
3144 G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1), 3158 G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1),
3145 G(DstMem | SrcImmByte | ModRM | Group, group1), 3159 G(DstMem | SrcImmByte | ModRM | Group, group1),
3146 I2bv(DstMem | SrcReg | ModRM, em_test), 3160 I2bv(DstMem | SrcReg | ModRM, em_test),
3147 D2bv(DstMem | SrcReg | ModRM | Lock), 3161 I2bv(DstMem | SrcReg | ModRM | Lock, em_xchg),
3148 /* 0x88 - 0x8F */ 3162 /* 0x88 - 0x8F */
3149 I2bv(DstMem | SrcReg | ModRM | Mov, em_mov), 3163 I2bv(DstMem | SrcReg | ModRM | Mov, em_mov),
3150 I2bv(DstReg | SrcMem | ModRM | Mov, em_mov), 3164 I2bv(DstReg | SrcMem | ModRM | Mov, em_mov),
@@ -3882,18 +3896,6 @@ special_insn:
3882 if (test_cc(c->b, ctxt->eflags)) 3896 if (test_cc(c->b, ctxt->eflags))
3883 jmp_rel(c, c->src.val); 3897 jmp_rel(c, c->src.val);
3884 break; 3898 break;
3885 case 0x86 ... 0x87: /* xchg */
3886 xchg:
3887 /* Write back the register source. */
3888 c->src.val = c->dst.val;
3889 write_register_operand(&c->src);
3890 /*
3891 * Write back the memory destination with implicit LOCK
3892 * prefix.
3893 */
3894 c->dst.val = c->src.orig_val;
3895 c->lock_prefix = 1;
3896 break;
3897 case 0x8c: /* mov r/m, sreg */ 3899 case 0x8c: /* mov r/m, sreg */
3898 if (c->modrm_reg > VCPU_SREG_GS) { 3900 if (c->modrm_reg > VCPU_SREG_GS) {
3899 rc = emulate_ud(ctxt); 3901 rc = emulate_ud(ctxt);
@@ -3929,7 +3931,8 @@ special_insn:
3929 case 0x90 ... 0x97: /* nop / xchg reg, rax */ 3931 case 0x90 ... 0x97: /* nop / xchg reg, rax */
3930 if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX]) 3932 if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX])
3931 break; 3933 break;
3932 goto xchg; 3934 rc = em_xchg(ctxt);
3935 break;
3933 case 0x98: /* cbw/cwde/cdqe */ 3936 case 0x98: /* cbw/cwde/cdqe */
3934 switch (c->op_bytes) { 3937 switch (c->op_bytes) {
3935 case 2: c->dst.val = (s8)c->dst.val; break; 3938 case 2: c->dst.val = (s8)c->dst.val; break;